diff options
| author | 2020-09-24 18:40:43 -0700 | |
|---|---|---|
| committer | 2020-09-25 18:41:41 -0700 | |
| commit | ed18d8085569642cd4507a14ecb1293cc4d19bf4 (patch) | |
| tree | 18ef368cf569fd9d460c8a1711347e58a36ce638 | |
| parent | f15229d4c5928408a4d45a00f34424c36d84d4e1 (diff) | |
Add and use ServiceProvider interface on fingerprint2.1
This interface should allow easy support for multiple HAL interfaces.
For example,
for (ServiceProvider p : providers) {
if (p.containsSensor(sensorId)) {
p.authenticate(sensorId, ...)
}
}
or,
ServiceProvider provider = getProviderFor(sensorId)
if (provider != null) provider.authenticate(sensorId, ...)
This should reduce lots of repeated null checks, sensorId checks,
etc. and give FingerprintService a easy way to perform operations
on providers, given a sensorId.
Some of the FingerprintManager code is not sensorId-specific,
but we can update those in the future. Otherwise we have to
touch multiple projects (settings, etc). For now, all client-side
code assumes only a single sensor, so that's what we'll support
from FingerprintService.
Bug: 168843828
Test: No effect on existing devices
Test: atest com.android.server.biometrics
Test: atest com.android.systemui.biometrics
Change-Id: Icca5bc1e128afa1bb7b2c05227e87567e564e4cf
14 files changed, 502 insertions, 128 deletions
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index c12bb39c3175..997efbedb0de 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -746,7 +746,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing * @hide */ @RequiresPermission(USE_BIOMETRIC_INTERNAL) - public void setUdfpsOverlayController(IUdfpsOverlayController controller) { + public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) { if (mService == null) { Slog.w(TAG, "setUdfpsOverlayController: no fingerprint service"); return; @@ -763,14 +763,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing * @hide */ @RequiresPermission(USE_BIOMETRIC_INTERNAL) - public void onFingerDown(int x, int y, float minor, float major) { + public void onFingerDown(int sensorId, int x, int y, float minor, float major) { if (mService == null) { Slog.w(TAG, "onFingerDown: no fingerprint service"); return; } try { - mService.onFingerDown(x, y, minor, major); + mService.onFingerDown(sensorId, x, y, minor, major); } catch (RemoteException e) { e.rethrowFromSystemServer(); } @@ -780,14 +780,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing * @hide */ @RequiresPermission(USE_BIOMETRIC_INTERNAL) - public void onFingerUp() { + public void onFingerUp(int sensorId) { if (mService == null) { Slog.w(TAG, "onFingerDown: no fingerprint service"); return; } try { - mService.onFingerUp(); + mService.onFingerUp(sensorId); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java index 718141a4845a..d26346c21427 100644 --- a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java +++ b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java @@ -18,9 +18,7 @@ package android.hardware.fingerprint; import android.annotation.IntDef; import android.hardware.biometrics.SensorProperties; -import android.hardware.face.FaceSensorProperties; import android.os.Parcel; -import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index cc2b520b3152..68013eae956b 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -121,10 +121,10 @@ interface IFingerprintService { void initializeConfiguration(int sensorId, int strength); // Notifies about a finger touching the sensor area. - void onFingerDown(int x, int y, float minor, float major); + void onFingerDown(int sensorId, int x, int y, float minor, float major); // Notifies about a finger leaving the sensor area. - void onFingerUp(); + void onFingerUp(int sensorId); // Sets the controller for managing the UDFPS overlay. void setUdfpsOverlayController(in IUdfpsOverlayController controller); diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl index a57726c4afe4..58b7046ad991 100644 --- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl +++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl @@ -21,11 +21,11 @@ package android.hardware.fingerprint; */ oneway interface IUdfpsOverlayController { // Shows the overlay. - void showUdfpsOverlay(); + void showUdfpsOverlay(int sensorId); // Hides the overlay. - void hideUdfpsOverlay(); + void hideUdfpsOverlay(int sensorId); // Shows debug messages on the UDFPS overlay. - void setDebugMessage(String message); + void setDebugMessage(int sensorId, String message); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index d79c96ea4774..289ffbe518c0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -16,6 +16,7 @@ package com.android.systemui.biometrics; +import static com.android.internal.util.Preconditions.checkArgument; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.SuppressLint; @@ -25,6 +26,7 @@ import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.Point; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.PowerManager; import android.os.UserHandle; @@ -41,6 +43,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.BrightnessSynchronizer; +import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.DozeReceiver; @@ -50,13 +53,22 @@ import com.android.systemui.util.settings.SystemSettings; import java.io.FileWriter; import java.io.IOException; +import java.util.List; import javax.inject.Inject; /** * Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events, * and coordinates triggering of the high-brightness mode (HBM). + * + * Note that the current architecture is designed so that a single {@link UdfpsController} + * controls/manages all UDFPS sensors. In other words, a single controller is registered with + * {@link com.android.server.biometrics.sensors.fingerprint.FingerprintService}, and interfaces such + * as {@link FingerprintManager#onFingerDown(int, int, int, float, float)} or + * {@link IUdfpsOverlayController#showUdfpsOverlay(int)}should all have + * {@code sensorId} parameters. */ +@SuppressWarnings("deprecation") class UdfpsController implements DozeReceiver { private static final String TAG = "UdfpsController"; // Gamma approximation for the sRGB color space. @@ -64,6 +76,10 @@ class UdfpsController implements DozeReceiver { private static final long AOD_INTERRUPT_TIMEOUT_MILLIS = 1000; private final FingerprintManager mFingerprintManager; + // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple + // sensors, this, in addition to a lot of the code here, will be updated. + @VisibleForTesting + final int mUdfpsSensorId; private final WindowManager mWindowManager; private final SystemSettings mSystemSettings; private final DelayableExecutor mFgExecutor; @@ -103,17 +119,17 @@ class UdfpsController implements DozeReceiver { public class UdfpsOverlayController extends IUdfpsOverlayController.Stub { @Override - public void showUdfpsOverlay() { + public void showUdfpsOverlay(int sensorId) { UdfpsController.this.setShowOverlay(true); } @Override - public void hideUdfpsOverlay() { + public void hideUdfpsOverlay(int sensorId) { UdfpsController.this.setShowOverlay(false); } @Override - public void setDebugMessage(String message) { + public void setDebugMessage(int sensorId, String message) { mView.setDebugMessage(message); } } @@ -165,6 +181,17 @@ class UdfpsController implements DozeReceiver { mFgExecutor = fgExecutor; mLayoutParams = createLayoutParams(context); + int udfpsSensorId = -1; + for (FingerprintSensorProperties props : mFingerprintManager.getSensorProperties()) { + if (props.isAnyUdfpsType()) { + udfpsSensorId = props.sensorId; + break; + } + } + // At least one UDFPS sensor exists + checkArgument(udfpsSensorId != -1); + mUdfpsSensorId = udfpsSensorId; + mView = (UdfpsView) inflater.inflate(R.layout.udfps_view, null, false); mHbmPath = resources.getString(R.string.udfps_hbm_sysfs_path); @@ -347,7 +374,7 @@ class UdfpsController implements DozeReceiver { fw.write(mHbmEnableCommand); fw.close(); } - mFingerprintManager.onFingerDown(x, y, minor, major); + mFingerprintManager.onFingerDown(mUdfpsSensorId, x, y, minor, major); } catch (IOException e) { mView.hideScrimAndDot(); Log.e(TAG, "onFingerDown | failed to enable HBM: " + e.getMessage()); @@ -355,7 +382,7 @@ class UdfpsController implements DozeReceiver { } private void onFingerUp() { - mFingerprintManager.onFingerUp(); + mFingerprintManager.onFingerUp(mUdfpsSensorId); // Hiding the scrim before disabling HBM results in less noticeable flicker. mView.hideScrimAndDot(); if (mHbmSupported) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 9b9f840e5383..7df9f1fff844 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -16,6 +16,8 @@ package com.android.systemui.biometrics; +import static junit.framework.Assert.assertEquals; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; @@ -25,7 +27,9 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.content.res.TypedArray; +import android.hardware.biometrics.SensorProperties; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.PowerManager; import android.os.RemoteException; @@ -54,11 +58,18 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.ArrayList; +import java.util.List; + @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper public class UdfpsControllerTest extends SysuiTestCase { + // Use this for inputs going into SystemUI. Use UdfpsController.mUdfpsSensorId for things + // leaving SystemUI. + private static final int TEST_UDFPS_SENSOR_ID = 1; + @Rule public MockitoRule rule = MockitoJUnit.rule(); @@ -98,6 +109,13 @@ public class UdfpsControllerTest extends SysuiTestCase { public void setUp() { setUpResources(); when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)).thenReturn(mUdfpsView); + final List<FingerprintSensorProperties> props = new ArrayList<>(); + props.add(new FingerprintSensorProperties(TEST_UDFPS_SENSOR_ID, + SensorProperties.STRENGTH_STRONG, + 5 /* maxEnrollmentsPerUser */, + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, + true /* resetLockoutRequiresHardwareAuthToken */)); + when(mFingerprintManager.getSensorProperties()).thenReturn(props); mSystemSettings = new FakeSettings(); mFgExecutor = new FakeExecutor(new FakeSystemClock()); mUdfpsController = new UdfpsController( @@ -112,6 +130,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mFgExecutor); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); + + assertEquals(TEST_UDFPS_SENSOR_ID, mUdfpsController.mUdfpsSensorId); } private void setUpResources() { @@ -138,15 +158,15 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void showUdfpsOverlay_addsViewToWindow() throws RemoteException { - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); verify(mWindowManager).addView(eq(mUdfpsView), any()); } @Test public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException { - mOverlayController.showUdfpsOverlay(); - mOverlayController.hideUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); + mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); verify(mWindowManager).removeView(eq(mUdfpsView)); } @@ -156,7 +176,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the bouncer is showing mUdfpsController.setBouncerVisibility(/* isShowing */ true); // WHEN a request to show the overlay is received - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); // THEN the overlay is not attached verify(mWindowManager, never()).addView(eq(mUdfpsView), any()); @@ -165,7 +185,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void setBouncerVisibility_overlayDetached() throws RemoteException { // GIVEN that the overlay has been requested - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); // WHEN the bouncer becomes visible mUdfpsController.setBouncerVisibility(/* isShowing */ true); mFgExecutor.runAllReady(); @@ -178,7 +198,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the bouncer is visible mUdfpsController.setBouncerVisibility(/* isShowing */ true); // AND the overlay has been requested - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); // WHEN the bouncer is closed mUdfpsController.setBouncerVisibility(/* isShowing */ false); mFgExecutor.runAllReady(); @@ -193,7 +213,7 @@ public class UdfpsControllerTest extends SysuiTestCase { when(mUdfpsView.isValidTouch(anyFloat(), anyFloat(), anyFloat())).thenReturn(true); // GIVEN that the overlay is showing - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); @@ -201,7 +221,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); event.recycle(); // THEN the event is passed to the FingerprintManager - verify(mFingerprintManager).onFingerDown(eq(0), eq(0), eq(0f), eq(0f)); + verify(mFingerprintManager).onFingerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0), + eq(0f), eq(0f)); // AND the scrim and dot is shown verify(mUdfpsView).showScrimAndDot(); } @@ -209,12 +230,13 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void aodInterrupt() throws RemoteException { // GIVEN that the overlay is showing - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); // WHEN fingerprint is requested because of AOD interrupt mUdfpsController.onAodInterrupt(0, 0); // THEN the event is passed to the FingerprintManager - verify(mFingerprintManager).onFingerDown(eq(0), eq(0), anyFloat(), anyFloat()); + verify(mFingerprintManager).onFingerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0), + anyFloat(), anyFloat()); // AND the scrim and dot is shown verify(mUdfpsView).showScrimAndDot(); } @@ -222,7 +244,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void cancelAodInterrupt() throws RemoteException { // GIVEN AOD interrupt - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0); // WHEN it is cancelled @@ -234,7 +256,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void aodInterruptTimeout() throws RemoteException { // GIVEN AOD interrupt - mOverlayController.showUdfpsOverlay(); + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0); // WHEN it times out diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 2903b9970033..cc9407913be9 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -46,6 +46,7 @@ import android.os.Process; import android.os.UserHandle; import android.provider.Settings; import android.util.EventLog; +import android.util.Pair; import android.util.Slog; import android.view.Surface; @@ -79,7 +80,7 @@ public class FingerprintService extends SystemService { private final LockoutResetDispatcher mLockoutResetDispatcher; private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher; private final LockPatternUtils mLockPatternUtils; - private Fingerprint21 mFingerprint21; + @NonNull private List<ServiceProvider> mServiceProviders; /** * Receives the incoming binder calls from FingerprintManager. @@ -88,11 +89,8 @@ public class FingerprintService extends SystemService { @Override // Binder call public List<FingerprintSensorProperties> getSensorProperties(String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - final List<FingerprintSensorProperties> properties = new ArrayList<>(); - - if (mFingerprint21 != null) { - properties.add(mFingerprint21.getFingerprintSensorProperties()); - } + final List<FingerprintSensorProperties> properties = + FingerprintService.this.getSensorProperties(); Slog.d(TAG, "Retrieved sensor properties for: " + opPackageName + ", sensors: " + properties.size()); @@ -104,18 +102,26 @@ public class FingerprintService extends SystemService { IFingerprintServiceReceiver receiver, String opPackageName) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - if (sensorId == mFingerprint21.getFingerprintSensorProperties().sensorId) { - mFingerprint21.scheduleGenerateChallenge(token, receiver, opPackageName); + final ServiceProvider provider = getProviderForSensor(sensorId); + if (provider == null) { + Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId); return; } - Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId); + provider.scheduleGenerateChallenge(sensorId, token, receiver, opPackageName); } @Override // Binder call - public void revokeChallenge(IBinder token, String owner) { + public void revokeChallenge(IBinder token, String opPackageName) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - mFingerprint21.scheduleRevokeChallenge(token, owner); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for revokeChallenge"); + return; + } + + provider.second.scheduleRevokeChallenge(provider.first, token, opPackageName); } @Override // Binder call @@ -123,14 +129,28 @@ public class FingerprintService extends SystemService { final IFingerprintServiceReceiver receiver, final String opPackageName, Surface surface) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - mFingerprint21.scheduleEnroll(token, hardwareAuthToken, userId, receiver, opPackageName, - surface); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for enroll"); + return; + } + + provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId, + receiver, opPackageName, surface); } @Override // Binder call public void cancelEnrollment(final IBinder token) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - mFingerprint21.cancelEnrollment(token); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for cancelEnrollment"); + return; + } + + provider.second.cancelEnrollment(provider.first, token); } @Override // Binder call @@ -169,8 +189,15 @@ public class FingerprintService extends SystemService { != PackageManager.PERMISSION_GRANTED; final int statsClient = isKeyguard ? BiometricsProtoEnums.CLIENT_KEYGUARD : BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER; - mFingerprint21.scheduleAuthenticate(token, operationId, userId, 0 /* cookie */, - new ClientMonitorCallbackConverter(receiver), opPackageName, + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for authenticate"); + return; + } + + provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, + 0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName, restricted, statsClient, isKeyguard); } @@ -191,7 +218,13 @@ public class FingerprintService extends SystemService { return; } - mFingerprint21.scheduleFingerDetect(token, userId, + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for detectFingerprint"); + return; + } + + provider.second.scheduleFingerDetect(provider.first, token, userId, new ClientMonitorCallbackConverter(receiver), opPackageName, surface, BiometricsProtoEnums.CLIENT_KEYGUARD); } @@ -203,8 +236,14 @@ public class FingerprintService extends SystemService { Surface surface) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for prepareForAuthentication"); + return; + } + final boolean restricted = true; // BiometricPrompt is always restricted - mFingerprint21.scheduleAuthenticate(token, operationId, userId, cookie, + provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, cookie, new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */); } @@ -212,7 +251,14 @@ public class FingerprintService extends SystemService { @Override // Binder call public void startPreparedClient(int cookie) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); - mFingerprint21.startPreparedClient(cookie); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for startPreparedClient"); + return; + } + + provider.second.startPreparedClient(provider.first, cookie); } @@ -228,7 +274,13 @@ public class FingerprintService extends SystemService { return; } - mFingerprint21.cancelAuthentication(token); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for cancelAuthentication"); + return; + } + + provider.second.cancelAuthentication(provider.first, token); } @Override // Binder call @@ -242,21 +294,41 @@ public class FingerprintService extends SystemService { // For IBiometricsFingerprint2.1, cancelling fingerprint detect is the same as // cancelling authentication. - mFingerprint21.cancelAuthentication(token); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for cancelFingerprintDetect"); + return; + } + + provider.second.cancelAuthentication(provider.first, token); } @Override // Binder call public void cancelAuthenticationFromService(final IBinder token, final String opPackageName, int callingUid, int callingPid, int callingUserId) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); - mFingerprint21.cancelAuthentication(token); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for cancelAuthenticationFromService"); + return; + } + + provider.second.cancelAuthentication(provider.first, token); } @Override // Binder call public void remove(final IBinder token, final int fingerId, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - mFingerprint21.scheduleRemove(token, receiver, fingerId, userId, opPackageName); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for remove"); + return; + } + provider.second.scheduleRemove(provider.first, token, receiver, fingerId, userId, + opPackageName); } @Override @@ -274,10 +346,14 @@ public class FingerprintService extends SystemService { final long ident = Binder.clearCallingIdentity(); try { - if (args.length > 0 && "--proto".equals(args[0])) { - mFingerprint21.dumpProto(fd); - } else { - mFingerprint21.dumpInternal(pw); + for (ServiceProvider provider : mServiceProviders) { + for (FingerprintSensorProperties props : provider.getSensorProperties()) { + if (args.length > 0 && "--proto".equals(args[0])) { + provider.dumpProto(props.sensorId, fd); + } else { + provider.dumpInternal(props.sensorId, pw); + } + } } } finally { Binder.restoreCallingIdentity(ident); @@ -294,11 +370,12 @@ public class FingerprintService extends SystemService { final long token = Binder.clearCallingIdentity(); try { - if (mFingerprint21 == null) { - Slog.e(TAG, "No HAL, caller: " + opPackageName); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName); return false; } - return mFingerprint21.isHardwareDetected(); + return provider.second.isHardwareDetected(provider.first); } finally { Binder.restoreCallingIdentity(token); } @@ -311,7 +388,13 @@ public class FingerprintService extends SystemService { return; } - mFingerprint21.rename(fingerId, userId, name); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for rename"); + return; + } + + provider.second.rename(provider.first, fingerId, userId, name); } @Override // Binder call @@ -325,7 +408,8 @@ public class FingerprintService extends SystemService { if (userId != UserHandle.getCallingUserId()) { Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS); } - return mFingerprint21.getEnrolledFingerprints(userId); + + return FingerprintService.this.getEnrolledFingerprints(userId, opPackageName); } @Override // Binder call @@ -339,19 +423,32 @@ public class FingerprintService extends SystemService { if (userId != UserHandle.getCallingUserId()) { Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS); } - return mFingerprint21.getEnrolledFingerprints(userId).size() > 0; + return !FingerprintService.this.getEnrolledFingerprints(userId, opPackageName) + .isEmpty(); } @Override // Binder call public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - return mFingerprint21.getLockoutModeForUser(userId); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for getLockoutModeForUser"); + return LockoutTracker.LOCKOUT_NONE; + } + return provider.second.getLockoutModeForUser(provider.first, userId); } @Override // Binder call public long getAuthenticatorId(int userId) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - return mFingerprint21.getAuthenticatorId(userId); + + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for getAuthenticatorId"); + return 0; + } + return provider.second.getAuthenticatorId(provider.first, userId); } @Override // Binder call @@ -359,12 +456,13 @@ public class FingerprintService extends SystemService { @Nullable byte [] hardwareAuthToken, String opPackageName) { Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT); - if (sensorId == mFingerprint21.getFingerprintSensorProperties().sensorId) { - mFingerprint21.scheduleResetLockout(userId); + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName); return; } - Slog.w(TAG, "No matching sensor for resetLockout, sensorId: " + sensorId); + provider.second.scheduleResetLockout(sensorId, userId, hardwareAuthToken); } @Override @@ -389,35 +487,52 @@ public class FingerprintService extends SystemService { public void initializeConfiguration(int sensorId, int strength) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); + final Fingerprint21 fingerprint21; if ((Build.IS_USERDEBUG || Build.IS_ENG) && getContext().getResources().getBoolean(R.bool.allow_test_udfps) && Settings.Secure.getIntForUser(getContext().getContentResolver(), Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */, UserHandle.USER_CURRENT) != 0) { - mFingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(), sensorId, + fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(), sensorId, strength, mLockoutResetDispatcher, mGestureAvailabilityDispatcher); } else { - mFingerprint21 = Fingerprint21.newInstance(getContext(), sensorId, strength, + fingerprint21 = Fingerprint21.newInstance(getContext(), sensorId, strength, mLockoutResetDispatcher, mGestureAvailabilityDispatcher); } + mServiceProviders.add(fingerprint21); } @Override - public void onFingerDown(int x, int y, float minor, float major) { + public void onFingerDown(int sensorId, int x, int y, float minor, float major) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - mFingerprint21.onFingerDown(x, y, minor, major); + + final ServiceProvider provider = getProviderForSensor(sensorId); + if (provider == null) { + Slog.w(TAG, "No matching provider for onFingerDown, sensorId: " + sensorId); + return; + } + provider.onFingerDown(sensorId, x, y, minor, major); } @Override - public void onFingerUp() { + public void onFingerUp(int sensorId) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - mFingerprint21.onFingerUp(); + + final ServiceProvider provider = getProviderForSensor(sensorId); + if (provider == null) { + Slog.w(TAG, "No matching provider for onFingerUp, sensorId: " + sensorId); + return; + } + provider.onFingerUp(sensorId); } @Override - public void setUdfpsOverlayController(IUdfpsOverlayController controller) { + public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); - mFingerprint21.setUdfpsOverlayController(controller); + + for (ServiceProvider provider : mServiceProviders) { + provider.setUdfpsOverlayController(controller); + } } } @@ -427,6 +542,7 @@ public class FingerprintService extends SystemService { mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher(); mLockoutResetDispatcher = new LockoutResetDispatcher(context); mLockPatternUtils = new LockPatternUtils(context); + mServiceProviders = new ArrayList<>(); } @Override @@ -434,6 +550,61 @@ public class FingerprintService extends SystemService { publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper()); } + @Nullable + private ServiceProvider getProviderForSensor(int sensorId) { + for (ServiceProvider provider : mServiceProviders) { + if (provider.containsSensor(sensorId)) { + return provider; + } + } + return null; + } + + /** + * For devices with only a single provider, returns that provider. If no providers, or multiple + * providers exist, returns null. + */ + @Nullable + private Pair<Integer, ServiceProvider> getSingleProvider() { + final List<FingerprintSensorProperties> properties = getSensorProperties(); + if (properties.size() != 1) { + return null; + } + + // Theoretically we can just return the first provider, but maybe this is easier to + // understand. + final int sensorId = properties.get(0).sensorId; + for (ServiceProvider provider : mServiceProviders) { + if (provider.containsSensor(sensorId)) { + return new Pair<>(sensorId, provider); + } + } + + Slog.e(TAG, "Single sensor, but provider not found"); + return null; + } + + @NonNull + private List<FingerprintSensorProperties> getSensorProperties() { + final List<FingerprintSensorProperties> properties = new ArrayList<>(); + + for (ServiceProvider provider : mServiceProviders) { + properties.addAll(provider.getSensorProperties()); + } + return properties; + } + + @NonNull + private List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) { + final Pair<Integer, ServiceProvider> provider = getSingleProvider(); + if (provider == null) { + Slog.w(TAG, "Null provider for getEnrolledFingerprints, caller: " + opPackageName); + return Collections.emptyList(); + } + + return provider.second.getEnrolledFingerprints(provider.first, userId); + } + /** * Checks for public API invocations to ensure that permissions, etc are granted/correct. */ diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java new file mode 100644 index 000000000000..1fcc58cd5833 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java @@ -0,0 +1,114 @@ +/* + * 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; +import android.hardware.fingerprint.IFingerprintServiceReceiver; +import android.hardware.fingerprint.IUdfpsOverlayController; +import android.os.IBinder; +import android.view.Surface; + +import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; +import com.android.server.biometrics.sensors.LockoutTracker; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.List; + +/** + * Superset of features/functionalities that HALs provide to the rest of the framework. This is + * more or less mapped to the public and private APIs that {@link FingerprintManager} provide, and + * is used at the system server layer to provide easy mapping between request and provider. + * + * Note that providers support both single-sensor and multi-sensor HALs. In either case, + * {@link FingerprintService} must ensure that providers are only requested to perform operations + * on sensors that they own. + * + * For methods other than {@link #containsSensor(int)}, the caller must ensure that the sensorId + * passed in is supported by the provider. For example, + * if (serviceProvider.containsSensor(sensorId)) { + * serviceProvider.operation(sensorId, ...); + * } + * + * For operations that are supported by some providers but not others, clients are required + * to check (e.g. via {@link FingerprintManager#getSensorProperties()}) to ensure that the code + * path isn't taken. ServiceProviders will provide a no-op for unsupported operations to + * fail safely. + */ +@SuppressWarnings("deprecation") +public interface ServiceProvider { + /** + * Checks if the specified sensor is owned by this provider. + */ + boolean containsSensor(int sensorId); + + @NonNull List<FingerprintSensorProperties> getSensorProperties(); + + void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken); + + void scheduleGenerateChallenge(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, String opPackageName); + + void scheduleRevokeChallenge(int sensorId, @NonNull IBinder token, + @NonNull String opPackageName); + + void scheduleEnroll(int sensorId, @NonNull IBinder token, byte[] hardwareAuthToken, int userId, + @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName, + @Nullable Surface surface); + + void cancelEnrollment(int sensorId, @NonNull IBinder token); + + void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, + @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, + @Nullable Surface surface, int statsClient); + + void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId, + int cookie, @NonNull ClientMonitorCallbackConverter callback, + @NonNull String opPackageName, boolean restricted, int statsClient, boolean isKeyguard); + + void startPreparedClient(int sensorId, int cookie); + + void cancelAuthentication(int sensorId, @NonNull IBinder token); + + void scheduleRemove(int sensorId, @NonNull IBinder token, + @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, + @NonNull String opPackageName); + + boolean isHardwareDetected(int sensorId); + + void rename(int sensorId, int fingerId, int userId, @NonNull String name); + + @NonNull List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId); + + @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId); + + long getAuthenticatorId(int sensorId, int userId); + + void onFingerDown(int sensorId, int x, int y, float minor, float major); + + void onFingerUp(int sensorId); + + void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller); + + void dumpProto(int sensorId, @NonNull FileDescriptor fd); + + void dumpInternal(int sensorId, @NonNull PrintWriter pw); +} 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 c87bfec85dc3..30cbf40398ab 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 @@ -66,6 +66,7 @@ import com.android.server.biometrics.sensors.PerformanceTracker; import com.android.server.biometrics.sensors.RemovalConsumer; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher; +import com.android.server.biometrics.sensors.fingerprint.ServiceProvider; import org.json.JSONArray; import org.json.JSONException; @@ -83,14 +84,14 @@ import java.util.Map; * Supports a single instance of the {@link android.hardware.biometrics.fingerprint.V2_1} or * its extended minor versions. */ -public class Fingerprint21 implements IHwBinder.DeathRecipient { +public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider { private static final String TAG = "Fingerprint21"; private static final int ENROLL_TIMEOUT_SEC = 60; final Context mContext; private final IActivityTaskManager mActivityTaskManager; - private final FingerprintSensorProperties mSensorProperties; + @NonNull private final FingerprintSensorProperties mSensorProperties; private final BiometricScheduler mScheduler; private final Handler mHandler; private final LockoutResetDispatcher mLockoutResetDispatcher; @@ -435,9 +436,6 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { @Nullable IUdfpsOverlayController getUdfpsOverlayController() { return mUdfpsOverlayController; } - @LockoutTracker.LockoutMode public int getLockoutModeForUser(int userId) { - return mLockoutTracker.getLockoutModeForUser(userId); - } private void scheduleLoadAuthenticatorIds() { // Note that this can be performed on the scheduler (as opposed to being done immediately @@ -466,7 +464,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { * correct. */ private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) { - final boolean hasEnrolled = !getEnrolledFingerprints(targetUserId).isEmpty(); + final boolean hasEnrolled = + !getEnrolledFingerprints(mSensorProperties.sensorId, targetUserId).isEmpty(); final FingerprintUpdateActiveUserClient client = new FingerprintUpdateActiveUserClient(mContext, mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorProperties.sensorId, mCurrentUserId, @@ -481,7 +480,21 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void scheduleResetLockout(int userId) { + @Override + public boolean containsSensor(int sensorId) { + return mSensorProperties.sensorId == sensorId; + } + + @Override + @NonNull + public List<FingerprintSensorProperties> getSensorProperties() { + final List<FingerprintSensorProperties> properties = new ArrayList<>(); + properties.add(mSensorProperties); + return properties; + } + + @Override + public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) { // Fingerprint2.1 keeps track of lockout in the framework. Let's just do it on the handler // thread. mHandler.post(() -> { @@ -489,7 +502,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void scheduleGenerateChallenge(@NonNull IBinder token, + @Override + public void scheduleGenerateChallenge(int sensorId, @NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName) { mHandler.post(() -> { final FingerprintGenerateChallengeClient client = @@ -500,7 +514,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void scheduleRevokeChallenge(@NonNull IBinder token, @NonNull String opPackageName) { + @Override + public void scheduleRevokeChallenge(int sensorId, @NonNull IBinder token, + @NonNull String opPackageName) { mHandler.post(() -> { final FingerprintRevokeChallengeClient client = new FingerprintRevokeChallengeClient( mContext, mLazyDaemon, token, opPackageName, mSensorProperties.sensorId); @@ -508,7 +524,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void scheduleEnroll(@NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, + @Override + public void scheduleEnroll(int sensorId, @NonNull IBinder token, + @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName, @Nullable Surface surface) { mHandler.post(() -> { @@ -531,13 +549,15 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void cancelEnrollment(@NonNull IBinder token) { + @Override + public void cancelEnrollment(int sensorId, @NonNull IBinder token) { mHandler.post(() -> { mScheduler.cancelEnrollment(token); }); } - public void scheduleFingerDetect(@NonNull IBinder token, int userId, + @Override + public void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, @NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName, @Nullable Surface surface, int statsClient) { mHandler.post(() -> { @@ -552,8 +572,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void scheduleAuthenticate(@NonNull IBinder token, long operationId, int userId, - int cookie, @NonNull ClientMonitorCallbackConverter listener, + @Override + public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, + int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName, boolean restricted, int statsClient, boolean isKeyguard) { mHandler.post(() -> { @@ -569,19 +590,22 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public void startPreparedClient(int cookie) { + @Override + public void startPreparedClient(int sensorId, int cookie) { mHandler.post(() -> { mScheduler.startPreparedClient(cookie); }); } - public void cancelAuthentication(@NonNull IBinder token) { + @Override + public void cancelAuthentication(int sensorId, @NonNull IBinder token) { mHandler.post(() -> { mScheduler.cancelAuthentication(token); }); } - public void scheduleRemove(@NonNull IBinder token, + @Override + public void scheduleRemove(int sensorId, @NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName) { mHandler.post(() -> { @@ -599,7 +623,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); - final List<Fingerprint> enrolledList = getEnrolledFingerprints(userId); + final List<Fingerprint> enrolledList = getEnrolledFingerprints( + mSensorProperties.sensorId, userId); final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient( mContext, mLazyDaemon, userId, mContext.getOpPackageName(), mSensorProperties.sensorId, enrolledList, FingerprintUtils.getInstance(), @@ -608,30 +633,37 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { }); } - public boolean isHardwareDetected() { + @Override + public boolean isHardwareDetected(int sensorId) { final IBiometricsFingerprint daemon = getDaemon(); return daemon != null; } - @NonNull public FingerprintSensorProperties getFingerprintSensorProperties() { - return mSensorProperties; - } - - public void rename(int fingerId, int userId, String name) { + @Override + public void rename(int sensorId, int fingerId, int userId, @NonNull String name) { mHandler.post(() -> { FingerprintUtils.getInstance().renameBiometricForUser(mContext, userId, fingerId, name); }); } - public List<Fingerprint> getEnrolledFingerprints(int userId) { + @Override + @NonNull + public List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId) { return FingerprintUtils.getInstance().getBiometricsForUser(mContext, userId); } - public long getAuthenticatorId(int userId) { + @Override + @LockoutTracker.LockoutMode public int getLockoutModeForUser(int sensorId, int userId) { + return mLockoutTracker.getLockoutModeForUser(userId); + } + + @Override + public long getAuthenticatorId(int sensorId, int userId) { return mAuthenticatorIds.get(userId); } - public void onFingerDown(int x, int y, float minor, float major) { + @Override + public void onFingerDown(int sensorId, int x, int y, float minor, float major) { final ClientMonitor<?> client = mScheduler.getCurrentClient(); if (!(client instanceof Udfps)) { Slog.w(TAG, "onFingerDown received during client: " + client); @@ -641,7 +673,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { udfps.onFingerDown(x, y, minor, major); } - public void onFingerUp() { + @Override + public void onFingerUp(int sensorId) { final ClientMonitor<?> client = mScheduler.getCurrentClient(); if (!(client instanceof Udfps)) { Slog.w(TAG, "onFingerDown received during client: " + client); @@ -651,11 +684,13 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { udfps.onFingerUp(); } - public void setUdfpsOverlayController(IUdfpsOverlayController controller) { + @Override + public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) { mUdfpsOverlayController = controller; } - public void dumpProto(FileDescriptor fd) { + @Override + public void dumpProto(int sensorId, FileDescriptor fd) { PerformanceTracker tracker = PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId); @@ -695,7 +730,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient { tracker.clear(); } - public void dumpInternal(@NonNull PrintWriter pw) { + @Override + public void dumpInternal(int sensorId, @NonNull PrintWriter pw) { PerformanceTracker performanceTracker = PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId); 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 6d8f241adbdc..d68671bcc679 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 @@ -46,6 +46,7 @@ import com.android.server.biometrics.sensors.LockoutResetDispatcher; import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher; import java.util.ArrayList; +import java.util.List; import java.util.Random; /** @@ -397,8 +398,9 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage // Schedule this only after we invoke onClientFinished for the previous client, so that // internal preemption logic is not run. - mFingerprint21.scheduleAuthenticate(token, operationId, user, cookie, - listener, opPackageName, restricted, statsClient, isKeyguard); + mFingerprint21.scheduleAuthenticate(mFingerprint21.mSensorProperties.sensorId, token, + operationId, user, cookie, listener, opPackageName, restricted, statsClient, + isKeyguard); } } @@ -451,12 +453,14 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage @Override @NonNull - public FingerprintSensorProperties getFingerprintSensorProperties() { - return mSensorProperties; + public List<FingerprintSensorProperties> getSensorProperties() { + final List<FingerprintSensorProperties> properties = new ArrayList<>(); + properties.add(mSensorProperties); + return properties; } @Override - public void onFingerDown(int x, int y, float minor, float major) { + public void onFingerDown(int sensorId, int x, int y, float minor, float major) { mHandler.post(() -> { Slog.d(TAG, "onFingerDown"); final AuthenticationConsumer lastAuthenticatedConsumer = @@ -503,7 +507,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage } @Override - public void onFingerUp() { + public void onFingerUp(int sensorId) { mHandler.post(() -> { Slog.d(TAG, "onFingerUp"); @@ -558,7 +562,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage // Things can happen before SysUI loads and sets the controller. if (controller != null) { Slog.d(TAG, "setDebugMessage: " + message); - controller.setDebugMessage(message); + controller.setDebugMessage(mSensorProperties.sensorId, message); } } catch (RemoteException e) { Slog.e(TAG, "Remote exception when sending message: " + message, e); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java index 8087e15b540d..0658f957fecb 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java @@ -79,7 +79,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi if (authenticated) { resetFailedAttempts(getTargetUserId()); - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); mCallback.onClientFinished(this, true /* success */); } else { final @LockoutTracker.LockoutMode int lockoutMode = @@ -92,7 +92,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi // Send the error, but do not invoke the FinishCallback yet. Since lockout is not // controlled by the HAL, the framework must stop the sensor before finishing the // client. - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); onErrorInternal(errorCode, 0 /* vendorCode */, false /* finish */); cancel(); } @@ -111,7 +111,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { // GroupId was never used. In fact, groupId is always the same as userId. getFreshDaemon().authenticate(mOperationId, getTargetUserId()); @@ -119,14 +119,14 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi Slog.e(TAG, "Remote exception when requesting auth", e); onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); mCallback.onClientFinished(this, false /* success */); } } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { getFreshDaemon().cancel(); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java index 5865617f4a44..cad2214891a7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java @@ -61,7 +61,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { getFreshDaemon().cancel(); } catch (RemoteException e) { @@ -80,14 +80,14 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId()); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting auth", e); onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); mCallback.onClientFinished(this, false /* success */); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java index 1b9fae9cf91a..b1030bf367e8 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java @@ -70,7 +70,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { // GroupId was never used. In fact, groupId is always the same as userId. getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec); @@ -78,14 +78,14 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint Slog.e(TAG, "Remote exception when requesting enroll", e); onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); mCallback.onClientFinished(this, false /* success */); } } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController); + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { getFreshDaemon().cancel(); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/UdfpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/UdfpsHelper.java index c71ecbf7577d..0f1d6b462cac 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/UdfpsHelper.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/UdfpsHelper.java @@ -62,23 +62,25 @@ public class UdfpsHelper { } } - static void showUdfpsOverlay(@Nullable IUdfpsOverlayController udfpsOverlayController) { + static void showUdfpsOverlay(int sensorId, + @Nullable IUdfpsOverlayController udfpsOverlayController) { if (udfpsOverlayController == null) { return; } try { - udfpsOverlayController.showUdfpsOverlay(); + udfpsOverlayController.showUdfpsOverlay(sensorId); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e); } } - static void hideUdfpsOverlay(@Nullable IUdfpsOverlayController udfpsOverlayController) { + static void hideUdfpsOverlay(int sensorId, + @Nullable IUdfpsOverlayController udfpsOverlayController) { if (udfpsOverlayController == null) { return; } try { - udfpsOverlayController.hideUdfpsOverlay(); + udfpsOverlayController.hideUdfpsOverlay(sensorId); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e); } |