diff options
18 files changed, 457 insertions, 278 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricOverlayConstants.java b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java new file mode 100644 index 000000000000..603b06ddabaa --- /dev/null +++ b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java @@ -0,0 +1,50 @@ +/* + * 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 android.hardware.biometrics; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Common constants for biometric overlays. + * @hide + */ +public interface BiometricOverlayConstants { + /** Unknown usage. */ + int REASON_UNKNOWN = 0; + /** User is about to enroll. */ + int REASON_ENROLL_FIND_SENSOR = 1; + /** User is enrolling. */ + int REASON_ENROLL_ENROLLING = 2; + /** Usage from BiometricPrompt. */ + int REASON_AUTH_BP = 3; + /** Usage from Keyguard. */ + int REASON_AUTH_KEYGUARD = 4; + /** Non-specific usage (from FingerprintManager). */ + int REASON_AUTH_OTHER = 5; + + @IntDef({REASON_UNKNOWN, + REASON_ENROLL_FIND_SENSOR, + REASON_ENROLL_ENROLLING, + REASON_AUTH_BP, + REASON_AUTH_KEYGUARD, + REASON_AUTH_OTHER}) + @Retention(RetentionPolicy.SOURCE) + @interface ShowReason {} +} diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl index f18360ff4108..938431df4f20 100644 --- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl +++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl @@ -22,13 +22,6 @@ import android.hardware.fingerprint.IUdfpsOverlayControllerCallback; * @hide */ oneway interface IUdfpsOverlayController { - const int REASON_UNKNOWN = 0; - const int REASON_ENROLL_FIND_SENSOR = 1; - const int REASON_ENROLL_ENROLLING = 2; - const int REASON_AUTH_BP = 3; // BiometricPrompt - const int REASON_AUTH_FPM_KEYGUARD = 4; // FingerprintManager usage from Keyguard - const int REASON_AUTH_FPM_OTHER = 5; // Other FingerprintManager usage - // Shows the overlay. void showUdfpsOverlay(int sensorId, int reason, IUdfpsOverlayControllerCallback callback); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 62b9fd44d800..751cc8a51bed 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -16,7 +16,7 @@ package com.android.systemui.biometrics; -import static android.hardware.fingerprint.IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD; +import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD; import static com.android.internal.util.Preconditions.checkArgument; import static com.android.internal.util.Preconditions.checkNotNull; @@ -32,6 +32,7 @@ import android.content.IntentFilter; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.RectF; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.display.DisplayManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; @@ -241,8 +242,8 @@ public class UdfpsController implements DozeReceiver { @NonNull IUdfpsOverlayControllerCallback callback) { mFgExecutor.execute(() -> { final UdfpsEnrollHelper enrollHelper; - if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR - || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) { + if (reason == BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR + || reason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING) { enrollHelper = new UdfpsEnrollHelper(mContext, reason); } else { enrollHelper = null; @@ -320,7 +321,7 @@ public class UdfpsController implements DozeReceiver { @Override public void onReceive(Context context, Intent intent) { if (mServerRequest != null - && mServerRequest.mRequestReason != REASON_AUTH_FPM_KEYGUARD + && mServerRequest.mRequestReason != REASON_AUTH_KEYGUARD && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: " + mServerRequest.mRequestReason); @@ -747,9 +748,9 @@ public class UdfpsController implements DozeReceiver { // This view overlaps the sensor area, so prevent it from being selectable // during a11y. - if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR - || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING - || reason == IUdfpsOverlayController.REASON_AUTH_BP) { + if (reason == BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR + || reason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING + || reason == BiometricOverlayConstants.REASON_AUTH_BP) { mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); } @@ -767,8 +768,8 @@ public class UdfpsController implements DozeReceiver { private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) { switch (reason) { - case IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR: - case IUdfpsOverlayController.REASON_ENROLL_ENROLLING: + case BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR: + case BiometricOverlayConstants.REASON_ENROLL_ENROLLING: UdfpsEnrollView enrollView = (UdfpsEnrollView) mInflater.inflate( R.layout.udfps_enroll_view, null); mView.addView(enrollView); @@ -780,7 +781,7 @@ public class UdfpsController implements DozeReceiver { mStatusBarOptional, mDumpManager ); - case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD: + case BiometricOverlayConstants.REASON_AUTH_KEYGUARD: UdfpsKeyguardView keyguardView = (UdfpsKeyguardView) mInflater.inflate(R.layout.udfps_keyguard_view, null); mView.addView(keyguardView); @@ -799,7 +800,7 @@ public class UdfpsController implements DozeReceiver { mKeyguardStateController, this ); - case IUdfpsOverlayController.REASON_AUTH_BP: + case BiometricOverlayConstants.REASON_AUTH_BP: // note: empty controller, currently shows no visual affordance UdfpsBpView bpView = (UdfpsBpView) mInflater.inflate(R.layout.udfps_bp_view, null); mView.addView(bpView); @@ -809,7 +810,7 @@ public class UdfpsController implements DozeReceiver { mStatusBarOptional, mDumpManager ); - case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER: + case BiometricOverlayConstants.REASON_AUTH_OTHER: UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView) mInflater.inflate(R.layout.udfps_fpm_other_view, null); mView.addView(authOtherView); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java index 19148e383005..c6d2192b5b05 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.graphics.PointF; -import android.hardware.fingerprint.IUdfpsOverlayController; +import android.hardware.biometrics.BiometricOverlayConstants; import android.os.Build; import android.os.UserHandle; import android.provider.Settings; @@ -119,7 +119,7 @@ public class UdfpsEnrollHelper { } boolean shouldShowProgressBar() { - return mEnrollReason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING; + return mEnrollReason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING; } void onEnrollmentProgress(int remaining) { 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 f5c6f981d101..e3566e78769e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -32,6 +32,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.TypedArray; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.SensorProperties; import android.hardware.display.DisplayManager; @@ -256,7 +257,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void dozeTimeTick() throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); mUdfpsController.dozeTimeTick(); verify(mUdfpsView).dozeTimeTick(); @@ -271,7 +272,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received @@ -294,7 +295,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received @@ -317,7 +318,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received @@ -340,7 +341,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received @@ -362,7 +363,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_MOVE is received @@ -384,7 +385,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN multiple touches are received @@ -404,7 +405,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void showUdfpsOverlay_addsViewToWindow() throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); verify(mWindowManager).addView(eq(mUdfpsView), any()); } @@ -412,7 +413,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); verify(mWindowManager).removeView(eq(mUdfpsView)); @@ -422,7 +423,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void hideUdfpsOverlay_resetsAltAuthBouncerWhenShowing() throws RemoteException { // GIVEN overlay was showing and the udfps bouncer is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); when(mStatusBarKeyguardViewManager.isShowingAlternateAuth()).thenReturn(true); // WHEN the overlay is hidden @@ -436,7 +437,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void testSubscribesToOrientationChangesWhenShowingOverlay() throws Exception { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); verify(mDisplayManager).registerDisplayListener(any(), eq(mHandler)); @@ -455,7 +456,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); @@ -479,7 +480,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void aodInterrupt() throws RemoteException { // GIVEN that the overlay is showing and screen is on mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); // WHEN fingerprint is requested because of AOD interrupt @@ -496,7 +497,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void cancelAodInterrupt() throws RemoteException { // GIVEN AOD interrupt mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); @@ -511,7 +512,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void aodInterruptTimeout() throws RemoteException { // GIVEN AOD interrupt mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOn(); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); @@ -527,7 +528,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void aodInterruptScreenOff() throws RemoteException { // GIVEN screen off mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mScreenObserver.onScreenTurnedOff(); mFgExecutor.runAllReady(); @@ -546,7 +547,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback); + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java index 996f0fd3a55f..4f7c6b012c23 100644 --- a/services/core/java/com/android/server/biometrics/Utils.java +++ b/services/core/java/com/android/server/biometrics/Utils.java @@ -50,7 +50,6 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; -import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Binder; import android.os.Build; import android.os.RemoteException; @@ -62,7 +61,6 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; -import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BaseClientMonitor; import java.util.List; @@ -541,14 +539,4 @@ public class Utils { throw new IllegalArgumentException("Unknown strength: " + strength); } } - - public static int getUdfpsAuthReason(@NonNull AuthenticationClient<?> client) { - if (client.isKeyguard()) { - return IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD; - } else if (client.isBiometricPrompt()) { - return IUdfpsOverlayController.REASON_AUTH_BP; - } else { - return IUdfpsOverlayController.REASON_AUTH_FPM_OTHER; - } - } } diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 6f38ed04cd96..85d6d7fb2f6a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -28,6 +28,7 @@ import android.content.pm.ApplicationInfo; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricsProtoEnums; import android.os.IBinder; import android.os.RemoteException; @@ -457,4 +458,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public boolean wasAuthAttempted() { return mAuthAttempted; } + + protected int getShowOverlayReason() { + if (isKeyguard()) { + return BiometricOverlayConstants.REASON_AUTH_KEYGUARD; + } else if (isBiometricPrompt()) { + return BiometricOverlayConstants.REASON_AUTH_BP; + } else { + return BiometricOverlayConstants.REASON_AUTH_OTHER; + } + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java index 9191b8b55989..2826e0c97305 100644 --- a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java @@ -19,7 +19,9 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.fingerprint.FingerprintManager; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; @@ -128,4 +130,15 @@ public abstract class EnrollClient<T> extends AcquisitionClient<T> implements En public boolean interruptsPrecedingClients() { return true; } + + protected int getOverlayReasonFromEnrollReason(@FingerprintManager.EnrollReason int reason) { + switch (reason) { + case FingerprintManager.ENROLL_FIND_SENSOR: + return BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR; + case FingerprintManager.ENROLL_ENROLL: + return BiometricOverlayConstants.REASON_ENROLL_ENROLLING; + default: + return BiometricOverlayConstants.REASON_UNKNOWN; + } + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java b/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java new file mode 100644 index 000000000000..6e2b9ef7010e --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java @@ -0,0 +1,144 @@ +/* + * 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.hardware.biometrics.BiometricOverlayConstants; +import android.hardware.fingerprint.ISidefpsController; +import android.hardware.fingerprint.IUdfpsOverlayController; +import android.hardware.fingerprint.IUdfpsOverlayControllerCallback; +import android.os.RemoteException; +import android.util.Slog; + +import java.util.Optional; +import java.util.function.Consumer; + +/** + * Single entry point & holder for controllers managing UI overlays for biometrics. + * + * For common operations, like {@link #show(int, int, AcquisitionClient)}, modalities are + * skipped if they are not present (provided as null via the constructor). + * + * Use the getters, such as {@link #ifUdfps(OverlayControllerConsumer)}, to get a controller for + * operations that are unique to a single modality. + */ +public final class SensorOverlays { + + private static final String TAG = "SensorOverlays"; + + @NonNull private final Optional<IUdfpsOverlayController> mUdfpsOverlayController; + @NonNull private final Optional<ISidefpsController> mSidefpsController; + + /** + * Create an overlay controller for each modality. + * + * @param udfpsOverlayController under display fps or null if not present on device + * @param sidefpsController side fps or null if not present on device + */ + public SensorOverlays( + @Nullable IUdfpsOverlayController udfpsOverlayController, + @Nullable ISidefpsController sidefpsController) { + mUdfpsOverlayController = Optional.ofNullable(udfpsOverlayController); + mSidefpsController = Optional.ofNullable(sidefpsController); + } + + /** + * Show the overlay. + * + * @param sensorId sensor id + * @param reason reason for showing + * @param client client performing operation + */ + public void show(int sensorId, @BiometricOverlayConstants.ShowReason int reason, + @NonNull AcquisitionClient<?> client) { + if (mSidefpsController.isPresent()) { + try { + mSidefpsController.get().show(); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when showing the side-fps overlay", e); + } + } + + if (mUdfpsOverlayController.isPresent()) { + final IUdfpsOverlayControllerCallback callback = + new IUdfpsOverlayControllerCallback.Stub() { + @Override + public void onUserCanceled() { + client.onUserCanceled(); + } + }; + + try { + mUdfpsOverlayController.get().showUdfpsOverlay(sensorId, reason, callback); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e); + } + } + } + + /** + * Hide the overlay. + * + * @param sensorId sensor id + */ + public void hide(int sensorId) { + if (mSidefpsController.isPresent()) { + try { + mSidefpsController.get().hide(); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when hiding the side-fps overlay", e); + } + } + + if (mUdfpsOverlayController.isPresent()) { + try { + mUdfpsOverlayController.get().hideUdfpsOverlay(sensorId); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e); + } + } + } + + /** + * Use the udfps controller, if present. + * @param consumer action + */ + public void ifUdfps(OverlayControllerConsumer<IUdfpsOverlayController> consumer) { + if (mUdfpsOverlayController.isPresent()) { + try { + consumer.accept(mUdfpsOverlayController.get()); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception using overlay controller", e); + } + } + } + + /** + * Consumer for a biometric overlay controller. + * + * This behaves like a normal {@link Consumer} except that it will trap and log + * any thrown {@link RemoteException}. + * + * @param <T> the type of the input to the operation + **/ + @FunctionalInterface + public interface OverlayControllerConsumer<T> { + /** Perform the operation. */ + void accept(T t) throws RemoteException; + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/SidefpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/SidefpsHelper.java deleted file mode 100644 index 474066c227d2..000000000000 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/SidefpsHelper.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.Nullable; -import android.hardware.fingerprint.ISidefpsController; -import android.os.RemoteException; -import android.util.Slog; - -/** - * Contains helper methods for side-fps fingerprint controller. - */ -public class SidefpsHelper { - private static final String TAG = "SidefpsHelper"; - - /** - * Shows the side-fps affordance - * @param sidefpsController controller that shows and hides the side-fps affordance - */ - public static void showOverlay(@Nullable ISidefpsController sidefpsController) { - if (sidefpsController == null) { - return; - } - - try { - sidefpsController.show(); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when showing the side-fps overlay", e); - } - } - - /** - * Hides the side-fps affordance - * @param sidefpsController controller that shows and hides the side-fps affordance - */ - public static void hideOverlay(@Nullable ISidefpsController sidefpsController) { - if (sidefpsController == null) { - return; - } - try { - sidefpsController.hide(); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when hiding the side-fps overlay", e); - } - } -} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java index 879c8a0317d7..29661d46f328 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java @@ -17,17 +17,12 @@ package com.android.server.biometrics.sensors.fingerprint; import android.annotation.NonNull; -import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IUdfpsOverlayController; -import android.hardware.fingerprint.IUdfpsOverlayControllerCallback; import android.os.RemoteException; import android.util.Slog; -import com.android.server.biometrics.sensors.AcquisitionClient; - /** * Contains helper methods for under-display fingerprint HIDL. */ @@ -68,88 +63,6 @@ public class UdfpsHelper { } } - public static int getReasonFromEnrollReason(@FingerprintManager.EnrollReason int reason) { - switch (reason) { - case FingerprintManager.ENROLL_FIND_SENSOR: - return IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR; - case FingerprintManager.ENROLL_ENROLL: - return IUdfpsOverlayController.REASON_ENROLL_ENROLLING; - default: - return IUdfpsOverlayController.REASON_UNKNOWN; - } - } - - public static void showUdfpsOverlay(int sensorId, int reason, - @Nullable IUdfpsOverlayController udfpsOverlayController, - @NonNull AcquisitionClient<?> client) { - if (udfpsOverlayController == null) { - return; - } - - final IUdfpsOverlayControllerCallback callback = - new IUdfpsOverlayControllerCallback.Stub() { - @Override - public void onUserCanceled() { - client.onUserCanceled(); - } - }; - - try { - udfpsOverlayController.showUdfpsOverlay(sensorId, reason, callback); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e); - } - } - - public static void hideUdfpsOverlay(int sensorId, - @Nullable IUdfpsOverlayController udfpsOverlayController) { - if (udfpsOverlayController == null) { - return; - } - try { - udfpsOverlayController.hideUdfpsOverlay(sensorId); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e); - } - } - - public static void onAcquiredGood(int sensorId, - @Nullable IUdfpsOverlayController udfpsOverlayController) { - if (udfpsOverlayController == null) { - return; - } - - try { - udfpsOverlayController.onAcquiredGood(sensorId); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when sending onAcquiredGood", e); - } - } - - public static void onEnrollmentProgress(int sensorId, int remaining, - @Nullable IUdfpsOverlayController udfpsOverlayController) { - if (udfpsOverlayController == null) { - return; - } - try { - udfpsOverlayController.onEnrollmentProgress(sensorId, remaining); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when sending onEnrollmentProgress", e); - } - } - - public static void onEnrollmentHelp(int sensorId, - @Nullable IUdfpsOverlayController udfpsOverlayController) { - if (udfpsOverlayController == null) { - return; - } - try { - udfpsOverlayController.onEnrollmentHelp(sensorId); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when sending onEnrollmentHelp", e); - } - } - public static boolean isValidAcquisitionMessage(@NonNull Context context, int acquireInfo, int vendorCode) { return FingerprintManager.getAcquiredString(context, acquireInfo, vendorCode) != null; diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 9d911e0a320b..db7f3d76b7ae 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -32,15 +32,14 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; -import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutConsumer; import com.android.server.biometrics.sensors.LockoutTracker; +import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.Udfps; -import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; import java.util.ArrayList; @@ -53,7 +52,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp private static final String TAG = "FingerprintAuthenticationClient"; @NonNull private final LockoutCache mLockoutCache; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; + @NonNull private final SensorOverlays mSensorOverlays; @NonNull private final FingerprintSensorPropertiesInternal mSensorProps; @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback; @@ -77,7 +76,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp false /* isKeyguardBypassEnabled */); setRequestId(requestId); mLockoutCache = lockoutCache; - mUdfpsOverlayController = udfpsOverlayController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */); mSensorProps = sensorProps; mALSProbeCallback = createALSCallback(false /* startWithClient */); } @@ -120,7 +119,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp if (authenticated) { mState = STATE_STOPPED; - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); } else { mState = STATE_STARTED_PAUSED_ATTEMPTED; } @@ -131,7 +130,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp // For UDFPS, notify SysUI that the illumination can be turned off. // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) { - UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId())); } super.onAcquired(acquiredInfo, vendorCode); @@ -145,27 +144,28 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp BiometricNotificationUtils.showBadCalibrationNotification(getContext()); } - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); } @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this), - mUdfpsOverlayController, this); + mSensorOverlays.show(getSensorId(), getShowOverlayReason(), this); + try { mCancellationSignal = getFreshDaemon().authenticate(mOperationId); } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); + try { mCancellationSignal.cancel(); } catch (RemoteException e) { @@ -235,7 +235,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp Slog.e(TAG, "Remote exception", e); } - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } @@ -252,7 +252,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp Slog.e(TAG, "Remote exception", e); } - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java index da91cdd981b9..ac3ce896049b 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.fingerprint.ISession; @@ -31,7 +32,7 @@ import com.android.server.biometrics.BiometricsProto; import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.DetectionConsumer; -import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; +import com.android.server.biometrics.sensors.SensorOverlays; /** * Performs fingerprint detection without exposing any matching information (e.g. accept/reject @@ -42,8 +43,7 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det private static final String TAG = "FingerprintDetectClient"; private final boolean mIsStrongBiometric; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; - + @NonNull private final SensorOverlays mSensorOverlays; @Nullable private ICancellationSignal mCancellationSignal; FingerprintDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon, @@ -57,7 +57,7 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); setRequestId(requestId); mIsStrongBiometric = isStrongBiometric; - mUdfpsOverlayController = udfpsOverlayController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController*/); } @Override @@ -68,7 +68,8 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); + try { mCancellationSignal.cancel(); } catch (RemoteException e) { @@ -79,14 +80,13 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, - mUdfpsOverlayController, this); + mSensorOverlays.show(getSensorId(), BiometricOverlayConstants.REASON_AUTH_KEYGUARD, this); + try { mCancellationSignal = getFreshDaemon().detectInteraction(); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting finger detect", e); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index c420c5c57241..ccb34aad3198 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -39,8 +39,8 @@ import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnrollClient; +import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; -import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper; import com.android.server.biometrics.sensors.fingerprint.Udfps; import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; @@ -49,8 +49,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { private static final String TAG = "FingerprintEnrollClient"; @NonNull private final FingerprintSensorPropertiesInternal mSensorProps; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; - @Nullable private final ISidefpsController mSidefpsController; + @NonNull private final SensorOverlays mSensorOverlays; private final @FingerprintManager.EnrollReason int mEnrollReason; @Nullable private ICancellationSignal mCancellationSignal; @@ -63,7 +62,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId, @NonNull FingerprintSensorPropertiesInternal sensorProps, - @Nullable IUdfpsOverlayController udfpsOvelayController, + @Nullable IUdfpsOverlayController udfpsOverlayController, @Nullable ISidefpsController sidefpsController, int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) { // UDFPS haptics occur when an image is acquired (instead of when the result is known) @@ -71,8 +70,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { 0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, !sensorProps.isAnyUdfpsType() /* shouldVibrate */); mSensorProps = sensorProps; - mUdfpsOverlayController = udfpsOvelayController; - mSidefpsController = sidefpsController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController); mMaxTemplatesPerUser = maxTemplatesPerUser; mEnrollReason = enrollReason; @@ -91,11 +89,11 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) { super.onEnrollResult(identifier, remaining); - UdfpsHelper.onEnrollmentProgress(getSensorId(), remaining, mUdfpsOverlayController); + mSensorOverlays.ifUdfps( + controller -> controller.onEnrollmentProgress(getSensorId(), remaining)); if (remaining == 0) { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); } } @@ -106,12 +104,14 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD && mSensorProps.isAnyUdfpsType()) { vibrateSuccess(); - UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.ifUdfps(controller -> controller.onAcquiredGood(getSensorId())); } - if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) { - UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController); - } + mSensorOverlays.ifUdfps(controller -> { + if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) { + controller.onEnrollmentHelp(getSensorId()); + } + }); super.onAcquired(acquiredInfo, vendorCode); } @@ -120,8 +120,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { public void onError(int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); } @Override @@ -133,8 +132,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); + if (mCancellationSignal != null) { try { mCancellationSignal.cancel(); @@ -149,10 +148,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), - UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), - mUdfpsOverlayController, this); - SidefpsHelper.showOverlay(mSidefpsController); + mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this); + BiometricNotificationUtils.cancelBadCalibrationNotification(getContext()); try { mCancellationSignal = getFreshDaemon().enroll( 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 7d95ec098fee..afb4d16a8814 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 @@ -31,11 +31,11 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; -import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; +import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.Udfps; import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; @@ -52,7 +52,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi private static final String TAG = "Biometrics/FingerprintAuthClient"; private final LockoutFrameworkImpl mLockoutFrameworkImpl; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; + @NonNull private final SensorOverlays mSensorOverlays; @NonNull private final FingerprintSensorPropertiesInternal mSensorProps; @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback; @@ -76,7 +76,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi false /* isKeyguardBypassEnabled */); setRequestId(requestId); mLockoutFrameworkImpl = lockoutTracker; - mUdfpsOverlayController = udfpsOverlayController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */); mSensorProps = sensorProps; mALSProbeCallback = createALSCallback(false /* startWithClient */); } @@ -112,7 +112,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi if (authenticated) { mState = STATE_STOPPED; resetFailedAttempts(getTargetUserId()); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); } else { mState = STATE_STARTED_PAUSED_ATTEMPTED; final @LockoutTracker.LockoutMode int lockoutMode = @@ -125,7 +125,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(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); onErrorInternal(errorCode, 0 /* vendorCode */, false /* finish */); cancel(); } @@ -140,7 +140,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi BiometricNotificationUtils.showBadCalibrationNotification(getContext()); } - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); } private void resetFailedAttempts(int userId) { @@ -168,8 +168,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this), - mUdfpsOverlayController, this); + mSensorOverlays.show(getSensorId(), getShowOverlayReason(), this); + try { // GroupId was never used. In fact, groupId is always the same as userId. getFreshDaemon().authenticate(mOperationId, getTargetUserId()); @@ -177,14 +177,15 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi Slog.e(TAG, "Remote exception when requesting auth", e); onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); + 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 147a20699b54..b854fb300ece 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 @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricFingerprintConstants; +import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -33,6 +34,7 @@ import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.AuthenticationConsumer; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.PerformanceTracker; +import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.Udfps; import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; @@ -48,7 +50,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> private static final String TAG = "FingerprintDetectClient"; private final boolean mIsStrongBiometric; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; + @NonNull private final SensorOverlays mSensorOverlays; private boolean mIsPointerDown; public FingerprintDetectClient(@NonNull Context context, @@ -61,13 +63,14 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); setRequestId(requestId); - mUdfpsOverlayController = udfpsOverlayController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController */); mIsStrongBiometric = isStrongBiometric; } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); + try { getFreshDaemon().cancel(); } catch (RemoteException e) { @@ -86,16 +89,15 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), - IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, - mUdfpsOverlayController, this); + mSensorOverlays.show(getSensorId(), BiometricOverlayConstants.REASON_AUTH_KEYGUARD, this); + 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(getSensorId(), mUdfpsOverlayController); + mSensorOverlays.hide(getSensorId()); 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 dc705346f534..1ebf44ca707f 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 @@ -35,7 +35,7 @@ import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnrollClient; -import com.android.server.biometrics.sensors.fingerprint.SidefpsHelper; +import com.android.server.biometrics.sensors.SensorOverlays; import com.android.server.biometrics.sensors.fingerprint.Udfps; import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper; @@ -49,8 +49,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint private static final String TAG = "FingerprintEnrollClient"; - @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; - @Nullable private final ISidefpsController mSidefpsController; + @NonNull private final SensorOverlays mSensorOverlays; private final @FingerprintManager.EnrollReason int mEnrollReason; private boolean mIsPointerDown; @@ -65,8 +64,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, true /* shouldVibrate */); - mUdfpsOverlayController = udfpsOverlayController; - mSidefpsController = sidefpsController; + mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController); mEnrollReason = enrollReason; if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) { @@ -95,10 +93,8 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), - UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), - mUdfpsOverlayController, this); - SidefpsHelper.showOverlay(mSidefpsController); + mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this); + BiometricNotificationUtils.cancelBadCalibrationNotification(getContext()); try { // GroupId was never used. In fact, groupId is always the same as userId. @@ -107,16 +103,15 @@ 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(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); mCallback.onClientFinished(this, false /* success */); } } @Override protected void stopHalOperation() { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); + try { getFreshDaemon().cancel(); } catch (RemoteException e) { @@ -131,11 +126,11 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) { super.onEnrollResult(identifier, remaining); - UdfpsHelper.onEnrollmentProgress(getSensorId(), remaining, mUdfpsOverlayController); + mSensorOverlays.ifUdfps( + controller -> controller.onEnrollmentProgress(getSensorId(), remaining)); if (remaining == 0) { - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); } } @@ -143,17 +138,18 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint public void onAcquired(int acquiredInfo, int vendorCode) { super.onAcquired(acquiredInfo, vendorCode); - if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) { - UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController); - } + mSensorOverlays.ifUdfps(controller -> { + if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) { + controller.onEnrollmentHelp(getSensorId()); + } + }); } @Override public void onError(int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); - UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); - SidefpsHelper.hideOverlay(mSidefpsController); + mSensorOverlays.hide(getSensorId()); } @Override diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/SensorOverlaysTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/SensorOverlaysTest.java new file mode 100644 index 000000000000..2f45fb94d434 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/SensorOverlaysTest.java @@ -0,0 +1,129 @@ +/* + * 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; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import android.hardware.biometrics.BiometricOverlayConstants; +import android.hardware.fingerprint.ISidefpsController; +import android.hardware.fingerprint.IUdfpsOverlayController; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; + +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.ArrayList; +import java.util.List; + +@Presubmit +@SmallTest +public class SensorOverlaysTest { + + private static final int SENSOR_ID = 11; + + @Rule public final MockitoRule mockito = MockitoJUnit.rule(); + + @Mock private IUdfpsOverlayController mUdfpsOverlayController; + @Mock private ISidefpsController mSidefpsController; + @Mock private AcquisitionClient<?> mAcquisitionClient; + + @Test + public void noopWhenBothNull() { + final SensorOverlays useless = new SensorOverlays(null, null); + useless.show(SENSOR_ID, 2, null); + useless.hide(SENSOR_ID); + } + + @Test + public void testProvidesUdfps() { + final List<IUdfpsOverlayController> udfps = new ArrayList<>(); + SensorOverlays sensorOverlays = new SensorOverlays(null, mSidefpsController); + + sensorOverlays.ifUdfps(udfps::add); + assertThat(udfps).isEmpty(); + + sensorOverlays = new SensorOverlays(mUdfpsOverlayController, mSidefpsController); + sensorOverlays.ifUdfps(udfps::add); + assertThat(udfps).containsExactly(mUdfpsOverlayController); + } + + @Test + public void testShow() throws Exception { + testShow(mUdfpsOverlayController, mSidefpsController); + } + + @Test + public void testShowUdfps() throws Exception { + testShow(mUdfpsOverlayController, null); + } + + @Test + public void testShowSidefps() throws Exception { + testShow(null, mSidefpsController); + } + + private void testShow(IUdfpsOverlayController udfps, ISidefpsController sidefps) + throws Exception { + final SensorOverlays sensorOverlays = new SensorOverlays(udfps, sidefps); + final int reason = BiometricOverlayConstants.REASON_UNKNOWN; + sensorOverlays.show(SENSOR_ID, reason, mAcquisitionClient); + + if (udfps != null) { + verify(mUdfpsOverlayController).showUdfpsOverlay(eq(SENSOR_ID), eq(reason), any()); + } + if (sidefps != null) { + verify(mSidefpsController).show(); + } + } + + @Test + public void testHide() throws Exception { + testHide(mUdfpsOverlayController, mSidefpsController); + } + + @Test + public void testHideUdfps() throws Exception { + testHide(mUdfpsOverlayController, null); + } + + @Test + public void testHideSidefps() throws Exception { + testHide(null, mSidefpsController); + } + + private void testHide(IUdfpsOverlayController udfps, ISidefpsController sidefps) + throws Exception { + final SensorOverlays sensorOverlays = new SensorOverlays(udfps, sidefps); + sensorOverlays.hide(SENSOR_ID); + + if (udfps != null) { + verify(mUdfpsOverlayController).hideUdfpsOverlay(eq(SENSOR_ID)); + } + if (sidefps != null) { + verify(mSidefpsController).hide(); + } + } +} |