diff options
author | 2024-06-05 16:07:21 +0000 | |
---|---|---|
committer | 2024-06-05 16:07:21 +0000 | |
commit | 0edf9f03cef9fb09cf47954db702ec89cbd8c07e (patch) | |
tree | 86db0a3ca25482ba167a7d169d348391af26406d | |
parent | 0f7badbed2ee68b132e74157459f3fe80f0b69b5 (diff) |
Revert "Letting View handle click and longclick detection"
This reverts commit 0f7badbed2ee68b132e74157459f3fe80f0b69b5.
Reason for revert:
Manual revert since the previous one was made by the culprit assistant
Change-Id: I8e065ef1747d67769316109ab2fe62e5721b5b40
5 files changed, 69 insertions, 133 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt index 4849e66d37d5..c51413a2cc78 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt @@ -26,7 +26,6 @@ import com.android.systemui.haptics.vibratorHelper import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.kosmos.testScope -import com.android.systemui.qs.qsTileFactory import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.TestScope @@ -42,7 +41,6 @@ class QSLongPressEffectTest : SysuiTestCase() { private val kosmos = testKosmos() private val vibratorHelper = kosmos.vibratorHelper - private val qsTile = kosmos.qsTileFactory.createTile("Test Tile") private val effectDuration = 400 private val lowTickDuration = 12 @@ -63,7 +61,6 @@ class QSLongPressEffectTest : SysuiTestCase() { vibratorHelper, kosmos.keyguardInteractor, ) - longPressEffect.qsTile = qsTile } @Test @@ -94,10 +91,8 @@ class QSLongPressEffectTest : SysuiTestCase() { // GIVEN an action down event occurs longPressEffect.handleActionDown() - // THEN the effect moves to the TIMEOUT_WAIT state and starts the wait - val action by collectLastValue(longPressEffect.actionType) + // THEN the effect moves to the TIMEOUT_WAIT state assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) - assertThat(action).isEqualTo(QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT) } @Test @@ -112,6 +107,20 @@ class QSLongPressEffectTest : SysuiTestCase() { } @Test + fun onActionUp_whileWaiting_performsClick() = + testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) { + // GIVEN an action is being collected + val action by collectLastValue(longPressEffect.actionType) + + // GIVEN an action up occurs + longPressEffect.handleActionUp() + + // THEN the action to invoke is the click action and the effect does not start + assertThat(action).isEqualTo(QSLongPressEffect.ActionType.CLICK) + assertEffectDidNotStart() + } + + @Test fun onWaitComplete_whileWaiting_beginsEffect() = testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) { // GIVEN the pressed timeout is complete @@ -212,10 +221,8 @@ class QSLongPressEffectTest : SysuiTestCase() { // GIVEN that the animator was cancelled longPressEffect.handleAnimationCancel() - // THEN the state goes to the timeout wait and the wait is posted - val action by collectLastValue(longPressEffect.actionType) + // THEN the state goes to the timeout wait assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT) - assertThat(action).isEqualTo(QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT) } @Test @@ -231,29 +238,6 @@ class QSLongPressEffectTest : SysuiTestCase() { assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE) } - @Test - fun onTileClick_whileWaiting_withQSTile_clicks() = - testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) { - // GIVEN that a click was detected - val couldClick = longPressEffect.onTileClick() - - // THEN the click is successful - assertThat(couldClick).isTrue() - } - - @Test - fun onTileClick_whileWaiting_withoutQSTile_cannotClick() = - testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) { - // GIVEN that no QSTile has been set - longPressEffect.qsTile = null - - // GIVEN that a click was detected - val couldClick = longPressEffect.onTileClick() - - // THEN the click is not successful - assertThat(couldClick).isFalse() - } - private fun testWithScope(initialize: Boolean = true, test: suspend TestScope.() -> Unit) = with(kosmos) { testScope.runTest { diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt index 30b958393b60..ea8d7d778851 100644 --- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt +++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt @@ -19,9 +19,7 @@ package com.android.systemui.haptics.qs import android.os.VibrationEffect import android.view.View import androidx.annotation.VisibleForTesting -import com.android.systemui.animation.Expandable import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor -import com.android.systemui.plugins.qs.QSTile import com.android.systemui.statusbar.VibratorHelper import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -53,10 +51,6 @@ constructor( var state = State.IDLE private set - /** The QSTile and Expandable used to perform a long-click and click actions */ - var qsTile: QSTile? = null - var expandable: Expandable? = null - /** Flow for view control and action */ private val _postedActionType = MutableStateFlow<ActionType?>(null) val actionType: Flow<ActionType?> = @@ -111,7 +105,6 @@ constructor( when (state) { State.IDLE -> { setState(State.TIMEOUT_WAIT) - _postedActionType.value = ActionType.WAIT_TAP_TIMEOUT } State.RUNNING_BACKWARDS -> _postedActionType.value = ActionType.CANCEL_ANIMATOR else -> {} @@ -119,9 +112,16 @@ constructor( } fun handleActionUp() { - if (state == State.RUNNING_FORWARD) { - _postedActionType.value = ActionType.REVERSE_ANIMATOR - setState(State.RUNNING_BACKWARDS) + when (state) { + State.TIMEOUT_WAIT -> { + _postedActionType.value = ActionType.CLICK + setState(State.IDLE) + } + State.RUNNING_FORWARD -> { + _postedActionType.value = ActionType.REVERSE_ANIMATOR + setState(State.RUNNING_BACKWARDS) + } + else -> {} } } @@ -129,7 +129,6 @@ constructor( when (state) { State.TIMEOUT_WAIT -> { setState(State.IDLE) - clearActionType() } State.RUNNING_FORWARD -> { _postedActionType.value = ActionType.REVERSE_ANIMATOR @@ -146,23 +145,18 @@ constructor( /** This function is called both when an animator completes or gets cancelled */ fun handleAnimationComplete() { - when (state) { - State.RUNNING_FORWARD -> { - setState(State.IDLE) - vibrate(snapEffect) - _postedActionType.value = ActionType.LONG_PRESS - } - State.RUNNING_BACKWARDS -> { - setState(State.IDLE) - clearActionType() - } - else -> {} + if (state == State.RUNNING_FORWARD) { + vibrate(snapEffect) + _postedActionType.value = ActionType.LONG_PRESS + } + if (state != State.TIMEOUT_WAIT) { + // This will happen if the animator did not finish by being cancelled + setState(State.IDLE) } } fun handleAnimationCancel() { setState(State.TIMEOUT_WAIT) - _postedActionType.value = ActionType.WAIT_TAP_TIMEOUT } fun handleTimeoutComplete() { @@ -196,22 +190,9 @@ constructor( effectDuration ) setState(State.IDLE) - clearActionType() return true } - fun onTileClick(): Boolean { - if (state == State.TIMEOUT_WAIT) { - setState(State.IDLE) - clearActionType() - qsTile?.let { - it.click(expandable) - return true - } - } - return false - } - enum class State { IDLE, /* The effect is idle waiting for touch input */ TIMEOUT_WAIT, /* The effect is waiting for a [PRESSED_TIMEOUT] period */ @@ -221,7 +202,7 @@ constructor( /* A type of action to perform on the view depending on the effect's state and logic */ enum class ActionType { - WAIT_TAP_TIMEOUT, + CLICK, LONG_PRESS, RESET_AND_LONG_PRESS, START_ANIMATOR, diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt index 92a55ef0e74f..4875f481cce6 100644 --- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt @@ -17,6 +17,8 @@ package com.android.systemui.haptics.qs import android.animation.ValueAnimator +import android.annotation.SuppressLint +import android.view.MotionEvent import android.view.ViewConfiguration import android.view.animation.AccelerateDecelerateInterpolator import androidx.core.animation.doOnCancel @@ -28,7 +30,6 @@ import com.android.app.tracing.coroutines.launch import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.qs.tileimpl.QSTileViewImpl import kotlinx.coroutines.DisposableHandle -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.filterNotNull object QSLongPressEffectViewBinder { @@ -40,6 +41,9 @@ object QSLongPressEffectViewBinder { ): DisposableHandle? { if (qsLongPressEffect == null) return null + // Set the touch listener as the long-press effect + setTouchListener(tile, qsLongPressEffect) + return tile.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { // Action to perform @@ -48,18 +52,18 @@ object QSLongPressEffectViewBinder { qsLongPressEffect.actionType.filterNotNull().collect { action -> when (action) { - QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT -> { - delay(ViewConfiguration.getTapTimeout().toLong()) - qsLongPressEffect.handleTimeoutComplete() + QSLongPressEffect.ActionType.CLICK -> { + tile.performClick() + qsLongPressEffect.clearActionType() } QSLongPressEffect.ActionType.LONG_PRESS -> { tile.prepareForLaunch() - qsLongPressEffect.qsTile?.longClick(qsLongPressEffect.expandable) + tile.performLongClick() qsLongPressEffect.clearActionType() } QSLongPressEffect.ActionType.RESET_AND_LONG_PRESS -> { tile.resetLongPressEffectProperties() - qsLongPressEffect.qsTile?.longClick(qsLongPressEffect.expandable) + tile.performLongClick() qsLongPressEffect.clearActionType() } QSLongPressEffect.ActionType.START_ANIMATOR -> { @@ -102,4 +106,22 @@ object QSLongPressEffectViewBinder { } } } + + @SuppressLint("ClickableViewAccessibility") + private fun setTouchListener(tile: QSTileViewImpl, longPressEffect: QSLongPressEffect?) { + tile.setOnTouchListener { _, event -> + when (event.actionMasked) { + MotionEvent.ACTION_DOWN -> { + tile.postDelayed( + { longPressEffect?.handleTimeoutComplete() }, + ViewConfiguration.getTapTimeout().toLong(), + ) + longPressEffect?.handleActionDown() + } + MotionEvent.ACTION_UP -> longPressEffect?.handleActionUp() + MotionEvent.ACTION_CANCEL -> longPressEffect?.handleActionCancel() + } + true + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt index 1c4404db1fb1..c6dfdd5c137b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt @@ -19,7 +19,6 @@ package com.android.systemui.qs.tileimpl import android.animation.ArgbEvaluator import android.animation.PropertyValuesHolder import android.animation.ValueAnimator -import android.annotation.SuppressLint import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration @@ -38,7 +37,6 @@ import android.util.Log import android.util.TypedValue import android.view.Gravity import android.view.LayoutInflater -import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent @@ -382,22 +380,15 @@ open class QSTileViewImpl @JvmOverloads constructor( override fun init(tile: QSTile) { val expandable = Expandable.fromView(this) - if (quickSettingsVisualHapticsLongpress()) { - isHapticFeedbackEnabled = false - longPressEffect?.qsTile = tile - longPressEffect?.expandable = expandable - init( - { _: View? -> longPressEffect?.onTileClick() }, - null, // Haptics and long-clicks will be handled by the [QSLongPressEffect] - ) - } else { - init( + init( { _: View? -> tile.click(expandable) }, { _: View? -> tile.longClick(expandable) true - }, - ) + } + ) + if (quickSettingsVisualHapticsLongpress()) { + isHapticFeedbackEnabled = false // Haptics will be handled by the [QSLongPressEffect] } } @@ -535,20 +526,6 @@ open class QSTileViewImpl @JvmOverloads constructor( return sb.toString() } - @SuppressLint("ClickableViewAccessibility") - override fun onTouchEvent(event: MotionEvent?): Boolean { - // let the View run the onTouch logic for click and long-click detection - val result = super.onTouchEvent(event) - if (longPressEffect != null) { - when (event?.actionMasked) { - MotionEvent.ACTION_DOWN -> longPressEffect.handleActionDown() - MotionEvent.ACTION_UP -> longPressEffect.handleActionUp() - MotionEvent.ACTION_CANCEL -> longPressEffect.handleActionCancel() - } - } - return result - } - // HANDLE STATE CHANGES RELATED METHODS protected open fun handleStateChanged(state: QSTile.State) { @@ -683,6 +660,7 @@ open class QSTileViewImpl @JvmOverloads constructor( // Long-press effects might have been enabled before but the new state does not // handle a long-press. In this case, we go back to the behaviour of a regular tile // and clean-up the resources + setOnTouchListener(null) unbindLongPressEffect() showRippleEffect = isClickable initialLongPressProperties = null diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt index 196f654a205a..db11c3e89160 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt @@ -19,8 +19,6 @@ package com.android.systemui.qs.tileimpl import android.content.Context import android.graphics.Rect import android.graphics.drawable.Drawable -import android.platform.test.annotations.DisableFlags -import android.platform.test.annotations.EnableFlags import android.service.quicksettings.Tile import android.testing.AndroidTestingRunner import android.testing.TestableLooper @@ -30,13 +28,11 @@ import android.view.View import android.view.accessibility.AccessibilityNodeInfo import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.Flags.FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.haptics.qs.QSLongPressEffect import com.android.systemui.haptics.qs.qsLongPressEffect import com.android.systemui.plugins.qs.QSTile -import com.android.systemui.qs.qsTileFactory import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -540,30 +536,10 @@ class QSTileViewImplTest : SysuiTestCase() { assertThat(tileView.haveLongPressPropertiesBeenReset).isTrue() } - @Test - @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) - fun onInit_withLongPressEffect_longPressEffectHasTileAndExpandable() { - val tile = kosmos.qsTileFactory.createTile("Test Tile") - tileView.init(tile) - - assertThat(tileView.isTileAddedToLongPress).isTrue() - assertThat(tileView.isExpandableAddedToLongPress).isTrue() - } - - @Test - @DisableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS) - fun onInit_withoutLongPressEffect_longPressEffectDoesNotHaveTileAndExpandable() { - val tile = kosmos.qsTileFactory.createTile("Test Tile") - tileView.init(tile) - - assertThat(tileView.isTileAddedToLongPress).isFalse() - assertThat(tileView.isExpandableAddedToLongPress).isFalse() - } - class FakeTileView( context: Context, collapsed: Boolean, - private val longPressEffect: QSLongPressEffect?, + longPressEffect: QSLongPressEffect?, ) : QSTileViewImpl( ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings), collapsed, @@ -571,11 +547,6 @@ class QSTileViewImplTest : SysuiTestCase() { ) { var constantLongPressEffectDuration = 500 - val isTileAddedToLongPress: Boolean - get() = longPressEffect?.qsTile != null - val isExpandableAddedToLongPress: Boolean - get() = longPressEffect?.expandable != null - override fun getLongPressEffectDuration(): Int = constantLongPressEffectDuration fun changeState(state: QSTile.State) { handleStateChanged(state) |