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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user