diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index c1554337c79e9..adc6a02e005fc 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1633,4 +1633,12 @@
Enable system animations for predictive back.
This setting enables system animations for predictive gesture animation. It requires setting per-app "enableOnBackInvokedCallback" to true in the manifest file.
+
+
+
+ - Move left
+ - Move down
+ - Move right
+ - Move up
+
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
rename to packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
index 7f3846ca4e40a..d55a027c2374b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.biometrics
+package com.android.settingslib.udfps
import android.graphics.Rect
import android.view.Surface
diff --git a/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java
new file mode 100644
index 0000000000000..c966757cc789c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2023 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.settingslib.udfps;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.DisplayUtils;
+import android.util.Log;
+import android.util.RotationUtils;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.MotionEvent;
+import android.view.Surface;
+
+import com.android.settingslib.R;
+
+/** Utility class for working with udfps. */
+public class UdfpsUtils {
+ private static final String TAG = "UdfpsUtils";
+
+ /**
+ * Gets the scale factor representing the user's current resolution / the stable (default)
+ * resolution.
+ *
+ * @param displayInfo The display information.
+ */
+ public float getScaleFactor(DisplayInfo displayInfo) {
+ Display.Mode maxDisplayMode =
+ DisplayUtils.getMaximumResolutionDisplayMode(displayInfo.supportedModes);
+ float scaleFactor =
+ DisplayUtils.getPhysicalPixelDisplaySizeRatio(
+ maxDisplayMode.getPhysicalWidth(),
+ maxDisplayMode.getPhysicalHeight(),
+ displayInfo.getNaturalWidth(),
+ displayInfo.getNaturalHeight()
+ );
+ return (scaleFactor == Float.POSITIVE_INFINITY) ? 1f : scaleFactor;
+ }
+
+ /**
+ * Gets the touch in native coordinates. Map the touch to portrait mode if the device is in
+ * landscape mode.
+ *
+ * @param idx The pointer identifier.
+ * @param event The MotionEvent object containing full information about the event.
+ * @param udfpsOverlayParams The [UdfpsOverlayParams] used.
+ * @return The mapped touch event.
+ */
+ public Point getTouchInNativeCoordinates(int idx, MotionEvent event,
+ UdfpsOverlayParams udfpsOverlayParams) {
+ Point portraitTouch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx));
+ int rot = udfpsOverlayParams.getRotation();
+ if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+ RotationUtils.rotatePoint(
+ portraitTouch,
+ RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
+ udfpsOverlayParams.getLogicalDisplayWidth(),
+ udfpsOverlayParams.getLogicalDisplayHeight()
+ );
+ }
+
+ // Scale the coordinates to native resolution.
+ float scale = udfpsOverlayParams.getScaleFactor();
+ portraitTouch.x = (int) (portraitTouch.x / scale);
+ portraitTouch.y = (int) (portraitTouch.y / scale);
+ return portraitTouch;
+ }
+
+ /**
+ * This function computes the angle of touch relative to the sensor and maps the angle to a list
+ * of help messages which are announced if accessibility is enabled.
+ *
+ * @return Whether the announcing string is null
+ */
+ public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled,
+ Context context, int touchX, int touchY, UdfpsOverlayParams udfpsOverlayParams) {
+ if (!touchExplorationEnabled) {
+ return null;
+ }
+
+ String[] touchHints = context.getResources().getStringArray(
+ R.array.udfps_accessibility_touch_hints);
+ if (touchHints.length != 4) {
+ Log.e(TAG, "expected exactly 4 touch hints, got " + touchHints.length + "?");
+ return null;
+ }
+
+ // Scale the coordinates to native resolution.
+ float scale = udfpsOverlayParams.getScaleFactor();
+ float scaledSensorX = udfpsOverlayParams.getSensorBounds().centerX() / scale;
+ float scaledSensorY = udfpsOverlayParams.getSensorBounds().centerY() / scale;
+ String theStr =
+ onTouchOutsideOfSensorAreaImpl(
+ touchHints,
+ touchX,
+ touchY,
+ scaledSensorX,
+ scaledSensorY,
+ udfpsOverlayParams.getRotation()
+ );
+ Log.v(TAG, "Announcing touch outside : $theStr");
+ return theStr;
+ }
+
+ /**
+ * This function computes the angle of touch relative to the sensor and maps the angle to a list
+ * of help messages which are announced if accessibility is enabled.
+ *
+ * There are 4 quadrants of the circle (90 degree arcs)
+ *
+ * [315, 360] && [0, 45) -> touchHints[0] = "Move Fingerprint to the left" [45, 135) ->
+ * touchHints[1] = "Move Fingerprint down" And so on.
+ */
+ private String onTouchOutsideOfSensorAreaImpl(String[] touchHints, float touchX,
+ float touchY, float sensorX, float sensorY, int rotation) {
+ float xRelativeToSensor = touchX - sensorX;
+ // Touch coordinates are with respect to the upper left corner, so reverse
+ // this calculation
+ float yRelativeToSensor = sensorY - touchY;
+ var angleInRad = Math.atan2(yRelativeToSensor, xRelativeToSensor);
+ // If the radians are negative, that means we are counting clockwise.
+ // So we need to add 360 degrees
+ if (angleInRad < 0.0) {
+ angleInRad += 2.0 * Math.PI;
+ }
+ // rad to deg conversion
+ double degrees = Math.toDegrees(angleInRad);
+ double degreesPerBucket = 360.0 / touchHints.length;
+ double halfBucketDegrees = degreesPerBucket / 2.0;
+ // The mapping should be as follows
+ // [315, 360] && [0, 45] -> 0
+ // [45, 135] -> 1
+ int index = (int) ((degrees + halfBucketDegrees) % 360 / degreesPerBucket);
+ index %= touchHints.length;
+
+ // A rotation of 90 degrees corresponds to increasing the index by 1.
+ if (rotation == Surface.ROTATION_90) {
+ index = (index + 1) % touchHints.length;
+ }
+ if (rotation == Surface.ROTATION_270) {
+ index = (index + 3) % touchHints.length;
+ }
+ return touchHints[index];
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java
new file mode 100644
index 0000000000000..f4f0ef9a163a4
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2023 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.settingslib.udfps;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.Surface;
+
+import com.android.settingslib.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class UdfpsUtilsTest {
+ @Rule
+ public final MockitoRule rule = MockitoJUnit.rule();
+
+ private Context mContext;
+ private String[] mTouchHints;
+ private UdfpsUtils mUdfpsUtils;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mTouchHints = mContext.getResources().getStringArray(
+ R.array.udfps_accessibility_touch_hints);
+ mUdfpsUtils = new UdfpsUtils();
+ }
+
+ @Test
+ public void testTouchOutsideAreaNoRotation() {
+ int rotation = Surface.ROTATION_0;
+ // touch at 0 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 0/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[0]);
+ // touch at 90 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, -1/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[1]);
+ // touch at 180 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ -1 /* touchX */, 0/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[2]);
+ // touch at 270 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 1/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[3]);
+ }
+
+
+ @Test
+ public void testTouchOutsideAreaNoRotation90Degrees() {
+ int rotation = Surface.ROTATION_90;
+ // touch at 0 degrees -> 90 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 0 /* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[1]);
+ // touch at 90 degrees -> 180 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, -1 /* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[2]);
+ // touch at 180 degrees -> 270 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ -1 /* touchX */, 0 /* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[3]);
+ // touch at 270 degrees -> 0 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 1/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[0]);
+ }
+
+
+ @Test
+ public void testTouchOutsideAreaNoRotation270Degrees() {
+ int rotation = Surface.ROTATION_270;
+ // touch at 0 degrees -> 270 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 0/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[3]);
+ // touch at 90 degrees -> 0 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, -1/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[0]);
+ // touch at 180 degrees -> 90 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ -1 /* touchX */, 0/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[1]);
+ // touch at 270 degrees -> 180 degrees
+ assertThat(
+ mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+ 0 /* touchX */, 1/* touchY */,
+ new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+ )
+ ).isEqualTo(mTouchHints[2]);
+ }
+}
diff --git a/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
index de43a5e8b0297..4799f8c5b6687 100644
--- a/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
+++ b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
@@ -19,4 +19,12 @@
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
+
+
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b535e60b7c25a..8d951645223e0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -910,14 +910,6 @@
Face recognized
-
-
- - Move left
- - Move down
- - Move right
- - Move up
-
-
Swipe up to try again
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index dad6ebe401849..c8cf5d775ddf1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -55,7 +55,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserManager;
-import android.util.DisplayUtils;
import android.util.Log;
import android.util.RotationUtils;
import android.util.SparseBooleanArray;
@@ -69,6 +68,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.os.SomeArgs;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
import com.android.systemui.CoreStartable;
import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
@@ -169,6 +170,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
@NonNull private final UserManager mUserManager;
@NonNull private final LockPatternUtils mLockPatternUtils;
@NonNull private final InteractionJankMonitor mInteractionJankMonitor;
+ @NonNull private final UdfpsUtils mUdfpsUtils;
private final @Background DelayableExecutor mBackgroundExecutor;
private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
@@ -578,17 +580,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
*/
private void updateSensorLocations() {
mDisplay.getDisplayInfo(mCachedDisplayInfo);
- final Display.Mode maxDisplayMode =
- DisplayUtils.getMaximumResolutionDisplayMode(mCachedDisplayInfo.supportedModes);
- final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
- maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
- mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight());
- if (scaleFactor == Float.POSITIVE_INFINITY) {
- mScaleFactor = 1f;
- } else {
- mScaleFactor = scaleFactor;
- }
-
+ mScaleFactor = mUdfpsUtils.getScaleFactor(mCachedDisplayInfo);
updateUdfpsLocation();
updateFingerprintLocation();
updateFaceLocation();
@@ -732,7 +724,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
@NonNull InteractionJankMonitor jankMonitor,
@Main Handler handler,
@Background DelayableExecutor bgExecutor,
- @NonNull VibratorHelper vibrator) {
+ @NonNull VibratorHelper vibrator,
+ @NonNull UdfpsUtils udfpsUtils) {
mContext = context;
mExecution = execution;
mUserManager = userManager;
@@ -753,6 +746,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
mSfpsEnrolledForUser = new SparseBooleanArray();
mFaceEnrolledForUser = new SparseBooleanArray();
mVibratorHelper = vibrator;
+ mUdfpsUtils = udfpsUtils;
mLogContextInteractor = logContextInteractor;
mBiometricPromptInteractor = biometricPromptInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 64d5518cd44d0..074928af13bda 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -50,10 +50,8 @@ import android.os.Trace;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.util.Log;
-import android.util.RotationUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.VelocityTracker;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -66,6 +64,8 @@ import com.android.internal.logging.InstanceId;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.FaceAuthApiRequestReason;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.biometrics.dagger.BiometricsBackground;
@@ -168,6 +168,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@NonNull private final SessionTracker mSessionTracker;
@NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
@NonNull private final SecureSettings mSecureSettings;
+ @NonNull private final UdfpsUtils mUdfpsUtils;
// 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.
@@ -266,7 +267,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
mUdfpsDisplayMode, mSecureSettings, requestId, reason, callback,
(view, event, fromUdfpsView) -> onTouch(requestId, event,
fromUdfpsView), mActivityLaunchAnimator, mFeatureFlags,
- mPrimaryBouncerInteractor, mAlternateBouncerInteractor)));
+ mPrimaryBouncerInteractor, mAlternateBouncerInteractor, mUdfpsUtils)));
}
@Override
@@ -475,27 +476,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
&& mOverlayParams.getSensorBounds().contains((int) x, (int) y);
}
- private Point getTouchInNativeCoordinates(@NonNull MotionEvent event, int idx) {
- Point portraitTouch = new Point(
- (int) event.getRawX(idx),
- (int) event.getRawY(idx)
- );
- final int rot = mOverlayParams.getRotation();
- if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
- RotationUtils.rotatePoint(portraitTouch,
- RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
- mOverlayParams.getLogicalDisplayWidth(),
- mOverlayParams.getLogicalDisplayHeight()
- );
- }
-
- // Scale the coordinates to native resolution.
- final float scale = mOverlayParams.getScaleFactor();
- portraitTouch.x = (int) (portraitTouch.x / scale);
- portraitTouch.y = (int) (portraitTouch.y / scale);
- return portraitTouch;
- }
-
private void tryDismissingKeyguard() {
if (!mOnFingerDown) {
playStartHaptic();
@@ -713,7 +693,8 @@ public class UdfpsController implements DozeReceiver, Dumpable {
break;
}
// Map the touch to portrait mode if the device is in landscape mode.
- final Point scaledTouch = getTouchInNativeCoordinates(event, idx);
+ final Point scaledTouch = mUdfpsUtils.getTouchInNativeCoordinates(
+ idx, event, mOverlayParams);
if (actionMoveWithinSensorArea) {
if (mVelocityTracker == null) {
// touches could be injected, so the velocity tracker may not have
@@ -757,16 +738,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
+ "but serverRequest is null");
return;
}
- // Scale the coordinates to native resolution.
- final float scale = mOverlayParams.getScaleFactor();
- final float scaledSensorX =
- mOverlayParams.getSensorBounds().centerX() / scale;
- final float scaledSensorY =
- mOverlayParams.getSensorBounds().centerY() / scale;
-
- mOverlay.onTouchOutsideOfSensorArea(
- scaledTouch.x, scaledTouch.y, scaledSensorX, scaledSensorY,
- mOverlayParams.getRotation());
+ mOverlay.onTouchOutsideOfSensorArea(scaledTouch);
});
}
}
@@ -838,7 +810,8 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@NonNull SinglePointerTouchProcessor singlePointerTouchProcessor,
@NonNull SessionTracker sessionTracker,
@NonNull AlternateBouncerInteractor alternateBouncerInteractor,
- @NonNull SecureSettings secureSettings) {
+ @NonNull SecureSettings secureSettings,
+ @NonNull UdfpsUtils udfpsUtils) {
mContext = context;
mExecution = execution;
mVibrator = vibrator;
@@ -880,6 +853,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
mPrimaryBouncerInteractor = primaryBouncerInteractor;
mAlternateBouncerInteractor = alternateBouncerInteractor;
mSecureSettings = secureSettings;
+ mUdfpsUtils = udfpsUtils;
mTouchProcessor = mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
? singlePointerTouchProcessor : null;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 45ca24d2df6e1..55bacef0b9774 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -20,6 +20,7 @@ import android.annotation.SuppressLint
import android.annotation.UiThread
import android.content.Context
import android.graphics.PixelFormat
+import android.graphics.Point
import android.graphics.Rect
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
@@ -46,6 +47,8 @@ import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan
import androidx.annotation.LayoutRes
import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsUtils
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dump.DumpManager
@@ -101,6 +104,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
private val alternateBouncerInteractor: AlternateBouncerInteractor,
private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
+ private val udfpsUtils: UdfpsUtils
) {
/** The view, when [isShowing], or null. */
var overlayView: UdfpsView? = null
@@ -239,7 +243,9 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
// Enroll udfps UI is handled by settings, so use empty view here
UdfpsFpmEmptyViewController(
- view.addUdfpsView(R.layout.udfps_fpm_empty_view),
+ view.addUdfpsView(R.layout.udfps_fpm_empty_view){
+ updateAccessibilityViewLocation(sensorBounds)
+ },
statusBarStateController,
shadeExpansionStateManager,
dialogManager,
@@ -348,81 +354,18 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
* the angle to a list of help messages which are announced if accessibility is enabled.
*
*/
- fun onTouchOutsideOfSensorArea(
- touchX: Float,
- touchY: Float,
- sensorX: Float,
- sensorY: Float,
- rotation: Int
- ) {
-
- if (!touchExplorationEnabled) {
- return
+ fun onTouchOutsideOfSensorArea(scaledTouch: Point) {
+ val theStr =
+ udfpsUtils.onTouchOutsideOfSensorArea(
+ touchExplorationEnabled,
+ context,
+ scaledTouch.x,
+ scaledTouch.y,
+ overlayParams
+ )
+ if (theStr != null) {
+ animationViewController?.doAnnounceForAccessibility(theStr)
}
- val touchHints =
- context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
- if (touchHints.size != 4) {
- Log.e(TAG, "expected exactly 4 touch hints, got $touchHints.size?")
- return
- }
- val theStr = onTouchOutsideOfSensorAreaImpl(touchX, touchY, sensorX, sensorY, rotation)
- Log.v(TAG, "Announcing touch outside : " + theStr)
- animationViewController?.doAnnounceForAccessibility(theStr)
- }
-
- /**
- * This function computes the angle of touch relative to the sensor and maps
- * the angle to a list of help messages which are announced if accessibility is enabled.
- *
- * There are 4 quadrants of the circle (90 degree arcs)
- *
- * [315, 360] && [0, 45) -> touchHints[0] = "Move Fingerprint to the left"
- * [45, 135) -> touchHints[1] = "Move Fingerprint down"
- * And so on.
- */
- fun onTouchOutsideOfSensorAreaImpl(
- touchX: Float,
- touchY: Float,
- sensorX: Float,
- sensorY: Float,
- rotation: Int
- ): String {
- val touchHints =
- context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-
- val xRelativeToSensor = touchX - sensorX
- // Touch coordinates are with respect to the upper left corner, so reverse
- // this calculation
- val yRelativeToSensor = sensorY - touchY
-
- var angleInRad =
- Math.atan2(yRelativeToSensor.toDouble(), xRelativeToSensor.toDouble())
- // If the radians are negative, that means we are counting clockwise.
- // So we need to add 360 degrees
- if (angleInRad < 0.0) {
- angleInRad += 2.0 * Math.PI
- }
- // rad to deg conversion
- val degrees = Math.toDegrees(angleInRad)
-
- val degreesPerBucket = 360.0 / touchHints.size
- val halfBucketDegrees = degreesPerBucket / 2.0
- // The mapping should be as follows
- // [315, 360] && [0, 45] -> 0
- // [45, 135] -> 1
- var index = (((degrees + halfBucketDegrees) % 360) / degreesPerBucket).toInt()
- index %= touchHints.size
-
- // A rotation of 90 degrees corresponds to increasing the index by 1.
- if (rotation == Surface.ROTATION_90) {
- index = (index + 1) % touchHints.size
- }
-
- if (rotation == Surface.ROTATION_270) {
- index = (index + 3) % touchHints.size
- }
-
- return touchHints[index]
}
/** Cancel this request. */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
index e8f041ec0d713..8352d0aeab350 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
@@ -16,7 +16,11 @@
package com.android.systemui.biometrics
import android.content.Context
+import android.graphics.Rect
import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.R
/**
* View corresponding with udfps_fpm_empty_view.xml
@@ -32,4 +36,13 @@ class UdfpsFpmEmptyView(
private val fingerprintDrawable: UdfpsFpDrawable = UdfpsFpDrawable(context)
override fun getDrawable(): UdfpsDrawable = fingerprintDrawable
+
+ fun updateAccessibilityViewLocation(sensorBounds: Rect) {
+ val fingerprintAccessibilityView: View = findViewById(R.id.udfps_enroll_accessibility_view)
+ val params: ViewGroup.LayoutParams = fingerprintAccessibilityView.layoutParams
+ params.width = sensorBounds.width()
+ params.height = sensorBounds.height()
+ fingerprintAccessibilityView.layoutParams = params
+ fingerprintAccessibilityView.requestLayout()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
index 802b9b6c02959..079c0b3f69665 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
@@ -32,6 +32,7 @@ import android.view.MotionEvent
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY
import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
index 4e6a06b1c44b5..28ca41d166a8f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
@@ -25,6 +25,7 @@ import android.graphics.RectF
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.FrameLayout
+import com.android.settingslib.udfps.UdfpsOverlayParams
private const val TAG = "UdfpsOverlayView"
private const val POINT_SIZE = 10f
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index e61c614f0292b..06dee7a2b9f6f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -26,6 +26,7 @@ import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.widget.FrameLayout
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.R
import com.android.systemui.doze.DozeReceiver
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
index 6f8efba2e84f7..67d2f308d3267 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics.dagger
+import com.android.settingslib.udfps.UdfpsUtils
import com.android.systemui.biometrics.data.repository.PromptRepository
import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
import com.android.systemui.biometrics.domain.interactor.CredentialInteractor
@@ -54,6 +55,9 @@ interface BiometricsModule {
@BiometricsBackground
fun providesPluginExecutor(threadFactory: ThreadFactory): Executor =
threadFactory.buildExecutorOnNewThread("biometrics")
+
+ @Provides
+ fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
index 39ea9368dacb3..234b383e20671 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
@@ -21,7 +21,7 @@ import android.util.RotationUtils
import android.view.MotionEvent
import android.view.MotionEvent.INVALID_POINTER_ID
import android.view.Surface
-import com.android.systemui.biometrics.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.biometrics.udfps.TouchProcessorResult.Failure
import com.android.systemui.biometrics.udfps.TouchProcessorResult.ProcessedTouch
import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
index ffcebf9cff754..4bf0ef69a4f94 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
@@ -17,7 +17,7 @@
package com.android.systemui.biometrics.udfps
import android.view.MotionEvent
-import com.android.systemui.biometrics.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsOverlayParams
/**
* Determines whether a finger entered or left the area of the under-display fingerprint sensor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 5afe49ea3cb32..0d00e8a85732b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -85,6 +85,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settingslib.udfps.UdfpsUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
@@ -167,6 +168,8 @@ public class AuthControllerTest extends SysuiTestCase {
private BiometricPromptCredentialInteractor mBiometricPromptCredentialInteractor;
@Mock
private CredentialViewModel mCredentialViewModel;
+ @Mock
+ private UdfpsUtils mUdfpsUtils;
@Captor
private ArgumentCaptor mFpAuthenticatorsRegisteredCaptor;
@@ -958,7 +961,7 @@ public class AuthControllerTest extends SysuiTestCase {
mPanelInteractionDetector, mUserManager, mLockPatternUtils, mUdfpsLogger,
mLogContextInteractor, () -> mBiometricPromptCredentialInteractor,
() -> mCredentialViewModel, mInteractionJankMonitor, mHandler,
- mBackgroundExecutor, mVibratorHelper);
+ mBackgroundExecutor, mVibratorHelper, mUdfpsUtils);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 36ed6d530539e..9866163febd0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -38,6 +38,8 @@ import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsUtils
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
@@ -110,6 +112,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
@Mock private lateinit var featureFlags: FeatureFlags
@Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
@Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
+ @Mock private lateinit var udfpsUtils: UdfpsUtils
@Captor private lateinit var layoutParamsCaptor: ArgumentCaptor
private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
@@ -144,7 +147,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
configurationController, keyguardStateController, unlockedScreenOffAnimationController,
udfpsDisplayMode, secureSettings, REQUEST_ID, reason,
controllerCallback, onTouch, activityLaunchAnimator, featureFlags,
- primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable
+ primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable, udfpsUtils
)
block()
}
@@ -400,109 +403,6 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
assertThat(controllerOverlay.matchesRequestId(REQUEST_ID)).isTrue()
assertThat(controllerOverlay.matchesRequestId(REQUEST_ID + 1)).isFalse()
}
-
- @Test
- fun testTouchOutsideAreaNoRotation() = withReason(REASON_ENROLL_ENROLLING) {
- val touchHints =
- context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
- val rotation = Surface.ROTATION_0
- // touch at 0 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[0])
- // touch at 90 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, -1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[1])
- // touch at 180 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- -1.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[2])
- // touch at 270 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[3])
- }
-
- fun testTouchOutsideAreaNoRotation90Degrees() = withReason(REASON_ENROLL_ENROLLING) {
- val touchHints =
- context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
- val rotation = Surface.ROTATION_90
- // touch at 0 degrees -> 90 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[1])
- // touch at 90 degrees -> 180 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, -1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[2])
- // touch at 180 degrees -> 270 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- -1.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[3])
- // touch at 270 degrees -> 0 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[0])
- }
-
- fun testTouchOutsideAreaNoRotation270Degrees() = withReason(REASON_ENROLL_ENROLLING) {
- val touchHints =
- context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
- val rotation = Surface.ROTATION_270
- // touch at 0 degrees -> 270 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[3])
- // touch at 90 degrees -> 0 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, -1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[0])
- // touch at 180 degrees -> 90 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- -1.0f /* x */, 0.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[1])
- // touch at 270 degrees -> 180 degrees
- assertThat(
- controllerOverlay.onTouchOutsideOfSensorAreaImpl(
- 0.0f /* x */, 1.0f /* y */,
- 0.0f /* sensorX */, 0.0f /* sensorY */, rotation
- )
- ).isEqualTo(touchHints[2])
- }
}
private class EnrollListener(
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 dd7082ad88fff..17c262dbbd9aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -71,6 +71,8 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -230,10 +232,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
private ScreenLifecycle.Observer mScreenObserver;
private FingerprintSensorPropertiesInternal mOpticalProps;
private FingerprintSensorPropertiesInternal mUltrasonicProps;
+ private UdfpsUtils mUdfpsUtils;
@Before
public void setUp() {
Execution execution = new FakeExecution();
+ mUdfpsUtils = new UdfpsUtils();
when(mLayoutInflater.inflate(R.layout.udfps_view, null, false))
.thenReturn(mUdfpsView);
@@ -305,7 +309,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
mUnlockedScreenOffAnimationController, mSystemUIDialogManager, mLatencyTracker,
mActivityLaunchAnimator, alternateTouchProvider, mBiometricExecutor,
mPrimaryBouncerInteractor, mSinglePointerTouchProcessor, mSessionTracker,
- mAlternateBouncerInteractor, mSecureSettings);
+ mAlternateBouncerInteractor, mSecureSettings, mUdfpsUtils);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 44fa4eb093083..07b4a649a6041 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -25,6 +25,7 @@ import android.testing.ViewUtils
import android.view.LayoutInflater
import android.view.Surface
import androidx.test.filters.SmallTest
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index 8e20303fd1892..c40fd4faf0070 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -23,8 +23,8 @@ import android.view.MotionEvent.PointerProperties
import android.view.Surface
import android.view.Surface.Rotation
import androidx.test.filters.SmallTest
+import com.android.settingslib.udfps.UdfpsOverlayParams
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.UdfpsOverlayParams
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith