diff options
9 files changed, 158 insertions, 48 deletions
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java index 9574fba62269..829dc4ff69f8 100644 --- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java +++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java @@ -54,8 +54,9 @@ public class UdfpsUtils { } /** - * Gets the touch in native coordinates. Map the touch to portrait mode if the device is in - * landscape mode. + * Gets the touch in native coordinates. + * + * Maps 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. @@ -64,35 +65,87 @@ public class UdfpsUtils { */ public Point getTouchInNativeCoordinates(int idx, MotionEvent event, UdfpsOverlayParams udfpsOverlayParams) { - Point portraitTouch = getPortraitTouch(idx, event, udfpsOverlayParams); + return getTouchInNativeCoordinates(idx, event, udfpsOverlayParams, true); + } + + /** + * Gets the touch in native coordinates. + * + * Optionally 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. + * @param rotateToPortrait Whether to rotate the touch to portrait orientation. + * @return The mapped touch event. + */ + public Point getTouchInNativeCoordinates(int idx, MotionEvent event, + UdfpsOverlayParams udfpsOverlayParams, boolean rotateToPortrait) { + Point touch; + if (rotateToPortrait) { + touch = getPortraitTouch(idx, event, udfpsOverlayParams); + } else { + touch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx)); + } // Scale the coordinates to native resolution. float scale = udfpsOverlayParams.getScaleFactor(); - portraitTouch.x = (int) (portraitTouch.x / scale); - portraitTouch.y = (int) (portraitTouch.y / scale); - return portraitTouch; + touch.x = (int) (touch.x / scale); + touch.y = (int) (touch.y / scale); + return touch; } /** * @param idx The pointer identifier. * @param event The MotionEvent object containing full information about the event. * @param udfpsOverlayParams The [UdfpsOverlayParams] used. - * @return Whether the touch event is within sensor area. + * @return Whether the touch event (that needs to be rotated to portrait) is within sensor area. */ public boolean isWithinSensorArea(int idx, MotionEvent event, UdfpsOverlayParams udfpsOverlayParams) { - Point portraitTouch = getPortraitTouch(idx, event, udfpsOverlayParams); - return udfpsOverlayParams.getSensorBounds().contains(portraitTouch.x, portraitTouch.y); + return isWithinSensorArea(idx, event, udfpsOverlayParams, true); + } + + /** + * @param idx The pointer identifier. + * @param event The MotionEvent object containing full information about the event. + * @param udfpsOverlayParams The [UdfpsOverlayParams] used. + * @param rotateTouchToPortrait Whether to rotate the touch coordinates to portrait. + * @return Whether the touch event is within sensor area. + */ + public boolean isWithinSensorArea(int idx, MotionEvent event, + UdfpsOverlayParams udfpsOverlayParams, boolean rotateTouchToPortrait) { + Point touch; + if (rotateTouchToPortrait) { + touch = getPortraitTouch(idx, event, udfpsOverlayParams); + } else { + touch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx)); + } + return udfpsOverlayParams.getSensorBounds().contains(touch.x, touch.y); + } + + /** + * This function computes the angle of touch relative to the sensor, rotated to portrait, + * and maps the angle to a list of help messages which are announced if accessibility is + * enabled. + * + * @return announcement string + */ + public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled, Context context, + int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams) { + return onTouchOutsideOfSensorArea(touchExplorationEnabled, context, scaledTouchX, + scaledTouchY, udfpsOverlayParams, true); } /** * 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 + * @return announcement string */ public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled, Context context, - int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams) { + int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams, + boolean touchRotatedToPortrait) { if (!touchExplorationEnabled) { return null; } @@ -116,7 +169,8 @@ public class UdfpsUtils { scaledTouchY, scaledSensorX, scaledSensorY, - udfpsOverlayParams.getRotation() + udfpsOverlayParams.getRotation(), + touchRotatedToPortrait ); Log.v(TAG, "Announcing touch outside : $theStr"); return theStr; @@ -132,7 +186,7 @@ public class UdfpsUtils { * touchHints[1] = "Move Fingerprint down" And so on. */ private String onTouchOutsideOfSensorAreaImpl(String[] touchHints, float touchX, - float touchY, float sensorX, float sensorY, int rotation) { + float touchY, float sensorX, float sensorY, int rotation, boolean rotatedToPortrait) { float xRelativeToSensor = touchX - sensorX; // Touch coordinates are with respect to the upper left corner, so reverse // this calculation @@ -153,13 +207,16 @@ public class UdfpsUtils { 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; + if (rotatedToPortrait) { + // 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/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 2c3ebe901850..9d79e8713625 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -400,14 +400,20 @@ public class UdfpsController implements DozeReceiver, Dumpable { if (!mOverlayParams.equals(overlayParams)) { mOverlayParams = overlayParams; - final boolean wasShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState(); - - // When the bounds change it's always necessary to re-create the overlay's window with - // new LayoutParams. If the overlay needs to be shown, this will re-create and show the - // overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden. - redrawOverlay(); - if (wasShowingAlternateBouncer) { - mKeyguardViewManager.showBouncer(true); + if (DeviceEntryUdfpsRefactor.isEnabled()) { + if (mOverlay != null && mOverlay.getRequestReason() == REASON_AUTH_KEYGUARD) { + mOverlay.updateOverlayParams(mOverlayParams); + } + } else { + final boolean wasShowingAlternateBouncer = + mAlternateBouncerInteractor.isVisibleState(); + // When the bounds change it's always to re-create the overlay's window with new + // LayoutParams. If the overlay needs to be shown, this will re-create and show the + // overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden. + redrawOverlay(); + if (wasShowingAlternateBouncer) { + mKeyguardViewManager.showBouncer(true); + } } } } @@ -850,7 +856,6 @@ public class UdfpsController implements DozeReceiver, Dumpable { mOverlay = null; mOrientationListener.disable(); - } private void unconfigureDisplay(View view) { @@ -859,7 +864,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { } if (DeviceEntryUdfpsRefactor.isEnabled()) { if (mUdfpsDisplayMode != null) { - mUdfpsDisplayMode.disable(null); // beverlt + mUdfpsDisplayMode.disable(null); } } else { if (view != null) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index 16865ca809d9..3a45db17b64c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -318,6 +318,15 @@ class UdfpsControllerOverlay @JvmOverloads constructor( addViewRunnable = null } + fun updateOverlayParams(updatedOverlayParams: UdfpsOverlayParams) { + DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode() + overlayParams = updatedOverlayParams + sensorBounds = updatedOverlayParams.sensorBounds + getTouchOverlay()?.let { + windowManager.updateViewLayout(it, coreLayoutParams.updateDimensions(null)) + } + } + fun inflateUdfpsAnimation( view: UdfpsView, controller: UdfpsController diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt index 5ae2ff0e3108..3112b673d724 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt @@ -17,6 +17,7 @@ package com.android.systemui.biometrics.domain.interactor import android.content.Context +import android.graphics.Rect import android.hardware.biometrics.SensorLocationInternal import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository import com.android.systemui.biometrics.shared.model.SensorLocation @@ -43,6 +44,7 @@ constructor( repository: FingerprintPropertyRepository, configurationInteractor: ConfigurationInteractor, displayStateInteractor: DisplayStateInteractor, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) { val propertiesInitialized: StateFlow<Boolean> = repository.propertiesInitialized val isUdfps: StateFlow<Boolean> = @@ -103,4 +105,13 @@ constructor( sensorLocation.scale = scale sensorLocation } + + /** + * Sensor location for the: + * - current physical display + * - current screen resolution + * - device's current orientation + */ + val udfpsSensorBounds: Flow<Rect> = + udfpsOverlayInteractor.udfpsOverlayParams.map { it.sensorBounds }.distinctUntilChanged() } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt index f5a88708ee2a..191d612d3668 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt @@ -54,9 +54,21 @@ abstract class UdfpsAccessibilityOverlayViewModel( fun onHoverEvent(v: View, event: MotionEvent): Boolean { val overlayParams = udfpsOverlayParams.value val scaledTouch: Point = - udfpsUtils.getTouchInNativeCoordinates(event.getPointerId(0), event, overlayParams) + udfpsUtils.getTouchInNativeCoordinates( + event.getPointerId(0), + event, + overlayParams, /* rotateToPortrait */ + false + ) - if (!udfpsUtils.isWithinSensorArea(event.getPointerId(0), event, overlayParams)) { + if ( + !udfpsUtils.isWithinSensorArea( + event.getPointerId(0), + event, + overlayParams, + /* rotateTouchToPortrait */ false + ) + ) { // view only receives motionEvents when [visible] which requires touchExplorationEnabled val announceStr = udfpsUtils.onTouchOutsideOfSensorArea( @@ -65,6 +77,7 @@ abstract class UdfpsAccessibilityOverlayViewModel( scaledTouch.x, scaledTouch.y, overlayParams, + /* touchRotatedToPortrait */ false ) if (announceStr != null) { v.announceForAccessibility(announceStr) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt index ded680c8baa3..df0b3dc3cbce 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt @@ -60,12 +60,12 @@ constructor( val iconLocation: Flow<IconLocation> = isSupported.flatMapLatest { supportsUI -> if (supportsUI) { - fingerprintPropertyInteractor.sensorLocation.map { sensorLocation -> + fingerprintPropertyInteractor.udfpsSensorBounds.map { bounds -> IconLocation( - left = (sensorLocation.centerX - sensorLocation.radius).toInt(), - top = (sensorLocation.centerY - sensorLocation.radius).toInt(), - right = (sensorLocation.centerX + sensorLocation.radius).toInt(), - bottom = (sensorLocation.centerY + sensorLocation.radius).toInt(), + left = bounds.left, + top = bounds.top, + right = bounds.right, + bottom = bounds.bottom, ) } } else { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java index 3dcb3f89c730..5b6aee697fec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java @@ -65,7 +65,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 0/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[0]); // touch at 90 degrees @@ -73,7 +74,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, -1/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[1]); // touch at 180 degrees @@ -81,7 +83,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, -1 /* touchX */, 0/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[2]); // touch at 270 degrees @@ -89,7 +92,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 1/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[3]); } @@ -103,7 +107,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 0 /* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[1]); // touch at 90 degrees -> 180 degrees @@ -111,7 +116,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, -1 /* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[2]); // touch at 180 degrees -> 270 degrees @@ -119,7 +125,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, -1 /* touchX */, 0 /* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[3]); // touch at 270 degrees -> 0 degrees @@ -127,7 +134,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 1/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[0]); } @@ -141,7 +149,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 0/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[3]); // touch at 90 degrees -> 0 degrees @@ -149,7 +158,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, -1/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[0]); // touch at 180 degrees -> 90 degrees @@ -157,7 +167,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, -1 /* touchX */, 0/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[1]); // touch at 270 degrees -> 180 degrees @@ -165,7 +176,8 @@ public class UdfpsUtilsTest extends SysuiTestCase { mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext, 0 /* touchX */, 1/* touchY */, new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL) + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL), + true /* rotatedToPortrait */ ) ).isEqualTo(mTouchHints[2]); } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt index 3d84291292c9..65dd411d5f05 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt @@ -28,6 +28,7 @@ import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardViewController import com.android.systemui.animation.DialogTransitionAnimator +import com.android.systemui.biometrics.AuthController import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.demomode.DemoModeController @@ -85,6 +86,7 @@ data class TestMocksModule( @get:Provides val activityStarter: ActivityStarter = mock(), @get:Provides val activityManagerWrapper: ActivityManagerWrapper = mock(), @get:Provides val ambientState: AmbientState = mock(), + @get:Provides val authController: AuthController = mock(), @get:Provides val bubbles: Optional<Bubbles> = Optional.of(mock()), @get:Provides val darkIconDispatcher: DarkIconDispatcher = mock(), @get:Provides val demoModeController: DemoModeController = mock(), diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt index 34a9c8ab7381..d1709d6c5ce6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt @@ -30,5 +30,6 @@ val Kosmos.fingerprintPropertyInteractor by Fixture { repository = fingerprintPropertyRepository, configurationInteractor = configurationInteractor, displayStateInteractor = displayStateInteractor, + udfpsOverlayInteractor = udfpsOverlayInteractor, ) } |