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
This commit is contained in:
Brad Hinegardner
2023-04-07 18:51:30 -04:00
parent b2c8f86c62
commit b455b10549
3 changed files with 30 additions and 14 deletions

View File

@@ -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)
}

View File

@@ -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
) {

View File

@@ -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) {