From b455b1054935b70cec2b84c4581f648a5f94d458 Mon Sep 17 00:00:00 2001 From: Brad Hinegardner Date: Fri, 7 Apr 2023 18:51:30 -0400 Subject: [PATCH] Lockscreen Shortcuts sometimes do not activate when long-pressing When calculating the distance, the upward-scaling shortcut was affecting the getX and getY positions, causing the touchSlop to think we moved our finger too much, which cancelled the animation. This change uses rawX and rawY as we don't want the scaling to affect the distance calculations. Bug: b/277381195 Test: Manually test the lockscreen shortcuts, ensure they activate as expected Change-Id: I75e5133f7fbda3a3ae8843e7d74ca2e71e62c0bd --- .../systemui/common/ui/view/MotionEventExt.kt | 18 +++++++++++++----- .../KeyguardQuickAffordanceOnTouchListener.kt | 16 +++++++++++----- .../KeyguardSettingsButtonOnTouchListener.kt | 10 ++++++---- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt index 26fc36dd3c9e0..81ed07653f26c 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt @@ -19,10 +19,18 @@ package com.android.systemui.common.ui.view import android.util.MathUtils import android.view.MotionEvent -/** Returns the distance from the position of this [MotionEvent] and the given coordinates. */ -fun MotionEvent.distanceFrom( - x: Float, - y: Float, +/** + * Returns the distance from the raw position of this [MotionEvent] and the given coordinates. + * Because this is all expected to be in the coordinate space of the display and not the view, + * applying mutations to the view (such as scaling animations) does not affect the distance + * measured. + * @param xOnDisplay the x coordinate relative to the display + * @param yOnDisplay the y coordinate relative to the display + * @return distance from the raw position of this [MotionEvent] and the given coordinates + */ +fun MotionEvent.rawDistanceFrom( + xOnDisplay: Float, + yOnDisplay: Float, ): Float { - return MathUtils.dist(this.x, this.y, x, y) + return MathUtils.dist(this.rawX, this.rawY, xOnDisplay, yOnDisplay) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt index 779095cd1d1e1..5745d6ae077e6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt @@ -26,7 +26,7 @@ import androidx.core.animation.CycleInterpolator import androidx.core.animation.ObjectAnimator import com.android.systemui.R import com.android.systemui.animation.Expandable -import com.android.systemui.common.ui.view.distanceFrom +import com.android.systemui.common.ui.view.rawDistanceFrom import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.VibratorHelper @@ -41,14 +41,14 @@ class KeyguardQuickAffordanceOnTouchListener( private val longPressDurationMs = ViewConfiguration.getLongPressTimeout().toLong() private var longPressAnimator: ViewPropertyAnimator? = null - private val down: PointF by lazy { PointF() } + private val downDisplayCoords: PointF by lazy { PointF() } @SuppressLint("ClickableViewAccessibility") override fun onTouch(v: View, event: MotionEvent): Boolean { return when (event.actionMasked) { MotionEvent.ACTION_DOWN -> if (viewModel.configKey != null) { - down.set(event.x, event.y) + downDisplayCoords.set(event.rawX, event.rawY) if (isUsingAccurateTool(event)) { // For accurate tool types (stylus, mouse, etc.), we don't require a // long-press. @@ -81,7 +81,13 @@ class KeyguardQuickAffordanceOnTouchListener( if (!isUsingAccurateTool(event)) { // Moving too far while performing a long-press gesture cancels that // gesture. - if (event.distanceFrom(down.x, down.y) > ViewConfiguration.getTouchSlop()) { + if ( + event + .rawDistanceFrom( + downDisplayCoords.x, + downDisplayCoords.y, + ) > ViewConfiguration.getTouchSlop() + ) { cancel() } } @@ -94,7 +100,7 @@ class KeyguardQuickAffordanceOnTouchListener( // the pointer performs a click. if ( viewModel.configKey != null && - event.distanceFrom(down.x, down.y) <= + event.rawDistanceFrom(downDisplayCoords.x, downDisplayCoords.y) <= ViewConfiguration.getTouchSlop() && falsingManager?.isFalseTap(FalsingManager.NO_PENALTY) == false ) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt index ad3fb637961ba..c54203c970136 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt @@ -21,7 +21,7 @@ import android.view.MotionEvent import android.view.View import android.view.ViewConfiguration import com.android.systemui.animation.view.LaunchableLinearLayout -import com.android.systemui.common.ui.view.distanceFrom +import com.android.systemui.common.ui.view.rawDistanceFrom import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel class KeyguardSettingsButtonOnTouchListener( @@ -29,18 +29,20 @@ class KeyguardSettingsButtonOnTouchListener( private val viewModel: KeyguardSettingsMenuViewModel, ) : View.OnTouchListener { - private val downPosition = PointF() + private val downPositionDisplayCoords = PointF() override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { when (motionEvent.actionMasked) { MotionEvent.ACTION_DOWN -> { view.isPressed = true - downPosition.set(motionEvent.x, motionEvent.y) + downPositionDisplayCoords.set(motionEvent.rawX, motionEvent.rawY) viewModel.onTouchGestureStarted() } MotionEvent.ACTION_UP -> { view.isPressed = false - val distanceMoved = motionEvent.distanceFrom(downPosition.x, downPosition.y) + val distanceMoved = + motionEvent + .rawDistanceFrom(downPositionDisplayCoords.x, downPositionDisplayCoords.y) val isClick = distanceMoved < ViewConfiguration.getTouchSlop() viewModel.onTouchGestureEnded(isClick) if (isClick) {