Merge "Apply falsing manager on seekbar" into tm-qpr-dev

This commit is contained in:
Michael Mikhail
2022-10-05 16:26:41 +00:00
committed by Android (Google) Code Review
7 changed files with 57 additions and 10 deletions

View File

@@ -45,6 +45,7 @@ public abstract class Classifier {
public static final int QS_SWIPE_SIDE = 15;
public static final int BACK_GESTURE = 16;
public static final int QS_SWIPE_NESTED = 17;
public static final int MEDIA_SEEKBAR = 18;
@IntDef({
QUICK_SETTINGS,
@@ -65,7 +66,8 @@ public abstract class Classifier {
LOCK_ICON,
QS_SWIPE_SIDE,
QS_SWIPE_NESTED,
BACK_GESTURE
BACK_GESTURE,
MEDIA_SEEKBAR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface InteractionType {}

View File

@@ -23,6 +23,7 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHT
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
@@ -153,6 +154,7 @@ class DistanceClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == BRIGHTNESS_SLIDER
|| interactionType == MEDIA_SEEKBAR
|| interactionType == SHADE_DRAG
|| interactionType == QS_COLLAPSE
|| interactionType == Classifier.UDFPS_AUTHENTICATION

View File

@@ -18,6 +18,7 @@ package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -119,7 +120,8 @@ class ProximityClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == QUICK_SETTINGS || interactionType == BRIGHTNESS_SLIDER
|| interactionType == QS_COLLAPSE || interactionType == QS_SWIPE_SIDE) {
|| interactionType == QS_COLLAPSE || interactionType == QS_SWIPE_SIDE
|| interactionType == MEDIA_SEEKBAR) {
return Result.passed(0);
}

View File

@@ -20,6 +20,7 @@ package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
@@ -93,6 +94,10 @@ public class TypeClassifier extends FalsingClassifier {
case QS_SWIPE_NESTED:
wrongDirection = !vertical;
break;
case MEDIA_SEEKBAR:
confidence = 0;
wrongDirection = vertical;
break;
default:
wrongDirection = true;
break;

View File

@@ -22,6 +22,7 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHT
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import static com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
import android.graphics.Point;
@@ -91,6 +92,7 @@ class ZigZagClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == BRIGHTNESS_SLIDER
|| interactionType == MEDIA_SEEKBAR
|| interactionType == SHADE_DRAG
|| interactionType == LOCK_ICON) {
return Result.passed(0);

View File

@@ -30,7 +30,10 @@ import androidx.annotation.WorkerThread
import androidx.core.view.GestureDetectorCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.util.concurrency.RepeatableExecutor
import javax.inject.Inject
@@ -72,7 +75,8 @@ private fun PlaybackState.computePosition(duration: Long): Long {
/** ViewModel for seek bar in QS media player. */
class SeekBarViewModel @Inject constructor(
@Background private val bgExecutor: RepeatableExecutor
@Background private val bgExecutor: RepeatableExecutor,
private val falsingManager: FalsingManager,
) {
private var _data = Progress(false, false, false, false, null, 0)
set(value) {
@@ -275,7 +279,7 @@ class SeekBarViewModel @Inject constructor(
/** Gets a listener to attach to the seek bar to handle seeking. */
val seekBarListener: SeekBar.OnSeekBarChangeListener
get() {
return SeekBarChangeListener(this)
return SeekBarChangeListener(this, falsingManager)
}
/** Attach touch handlers to the seek bar view. */
@@ -315,7 +319,8 @@ class SeekBarViewModel @Inject constructor(
}
private class SeekBarChangeListener(
val viewModel: SeekBarViewModel
val viewModel: SeekBarViewModel,
val falsingManager: FalsingManager,
) : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(bar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
@@ -328,6 +333,13 @@ class SeekBarViewModel @Inject constructor(
}
override fun onStopTrackingTouch(bar: SeekBar) {
// in addition to the normal functionality of both functions.
// isFalseTouch returns true if there is a real/false tap since it is not a move.
// isFalseTap returns true if there is a real/false move since it is not a tap.
if (falsingManager.isFalseTouch(MEDIA_SEEKBAR) &&
falsingManager.isFalseTap(LOW_PENALTY)) {
viewModel.onSeekFalse()
}
viewModel.onSeek(bar.progress.toLong())
}
}
@@ -340,7 +352,7 @@ class SeekBarViewModel @Inject constructor(
*/
private class SeekBarTouchListener(
private val viewModel: SeekBarViewModel,
private val bar: SeekBar
private val bar: SeekBar,
) : View.OnTouchListener, GestureDetector.OnGestureListener {
// Gesture detector helps decide which touch events to intercept.

View File

@@ -26,13 +26,13 @@ import android.widget.SeekBar
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.arch.core.executor.TaskExecutor
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.Classifier
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.concurrency.FakeRepeatableExecutor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Ignore
@@ -47,8 +47,8 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -70,6 +70,8 @@ public class SeekBarViewModelTest : SysuiTestCase() {
}
@Mock private lateinit var mockController: MediaController
@Mock private lateinit var mockTransport: MediaController.TransportControls
@Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var mockBar: SeekBar
private val token1 = MediaSession.Token(1, null)
private val token2 = MediaSession.Token(2, null)
@@ -78,9 +80,10 @@ public class SeekBarViewModelTest : SysuiTestCase() {
@Before
fun setUp() {
fakeExecutor = FakeExecutor(FakeSystemClock())
viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor))
viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor), falsingManager)
viewModel.logSeek = { }
whenever(mockController.sessionToken).thenReturn(token1)
whenever(mockBar.context).thenReturn(context)
// LiveData to run synchronously
ArchTaskExecutor.getInstance().setDelegate(taskExecutor)
@@ -453,6 +456,25 @@ public class SeekBarViewModelTest : SysuiTestCase() {
verify(mockTransport).seekTo(eq(pos.toLong()))
}
@Test
fun onFalseTapOrTouch() {
whenever(mockController.getTransportControls()).thenReturn(mockTransport)
whenever(falsingManager.isFalseTouch(Classifier.MEDIA_SEEKBAR)).thenReturn(true)
whenever(falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)).thenReturn(true)
viewModel.updateController(mockController)
val pos = 169
viewModel.attachTouchHandlers(mockBar)
with(viewModel.seekBarListener) {
onStartTrackingTouch(mockBar)
onProgressChanged(mockBar, pos, true)
onStopTrackingTouch(mockBar)
}
// THEN transport controls should not be used
verify(mockTransport, never()).seekTo(pos.toLong())
}
@Test
fun queuePollTaskWhenPlaying() {
// GIVEN that the track is playing