Merge "Apply falsing manager on seekbar" into tm-qpr-dev am: 9d5386156a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19902246

Change-Id: I55c8d51b477a4012a4df812837ed9d80ed54e59e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Michael Mikhail
2022-10-05 16:56:32 +00:00
committed by Automerger Merge Worker
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 QS_SWIPE_SIDE = 15;
public static final int BACK_GESTURE = 16; public static final int BACK_GESTURE = 16;
public static final int QS_SWIPE_NESTED = 17; public static final int QS_SWIPE_NESTED = 17;
public static final int MEDIA_SEEKBAR = 18;
@IntDef({ @IntDef({
QUICK_SETTINGS, QUICK_SETTINGS,
@@ -65,7 +66,8 @@ public abstract class Classifier {
LOCK_ICON, LOCK_ICON,
QS_SWIPE_SIDE, QS_SWIPE_SIDE,
QS_SWIPE_NESTED, QS_SWIPE_NESTED,
BACK_GESTURE BACK_GESTURE,
MEDIA_SEEKBAR,
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface InteractionType {} 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_FLING_THRESHOLD_IN;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_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.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_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED; import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG; import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
@@ -153,6 +154,7 @@ class DistanceClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType, @Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) { double historyBelief, double historyConfidence) {
if (interactionType == BRIGHTNESS_SLIDER if (interactionType == BRIGHTNESS_SLIDER
|| interactionType == MEDIA_SEEKBAR
|| interactionType == SHADE_DRAG || interactionType == SHADE_DRAG
|| interactionType == QS_COLLAPSE || interactionType == QS_COLLAPSE
|| interactionType == Classifier.UDFPS_AUTHENTICATION || 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.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.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_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE; import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -119,7 +120,8 @@ class ProximityClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType, @Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) { double historyBelief, double historyConfidence) {
if (interactionType == QUICK_SETTINGS || interactionType == BRIGHTNESS_SLIDER 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); 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.BOUNCER_UNLOCK;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER; 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.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_DISMISS;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN; import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND; import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
@@ -93,6 +94,10 @@ public class TypeClassifier extends FalsingClassifier {
case QS_SWIPE_NESTED: case QS_SWIPE_NESTED:
wrongDirection = !vertical; wrongDirection = !vertical;
break; break;
case MEDIA_SEEKBAR:
confidence = 0;
wrongDirection = vertical;
break;
default: default:
wrongDirection = true; wrongDirection = true;
break; 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.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.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.LOCK_ICON; 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 static com.android.systemui.classifier.Classifier.SHADE_DRAG;
import android.graphics.Point; import android.graphics.Point;
@@ -91,6 +92,7 @@ class ZigZagClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType, @Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) { double historyBelief, double historyConfidence) {
if (interactionType == BRIGHTNESS_SLIDER if (interactionType == BRIGHTNESS_SLIDER
|| interactionType == MEDIA_SEEKBAR
|| interactionType == SHADE_DRAG || interactionType == SHADE_DRAG
|| interactionType == LOCK_ICON) { || interactionType == LOCK_ICON) {
return Result.passed(0); return Result.passed(0);

View File

@@ -30,7 +30,10 @@ import androidx.annotation.WorkerThread
import androidx.core.view.GestureDetectorCompat import androidx.core.view.GestureDetectorCompat
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR
import com.android.systemui.dagger.qualifiers.Background 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.statusbar.NotificationMediaManager
import com.android.systemui.util.concurrency.RepeatableExecutor import com.android.systemui.util.concurrency.RepeatableExecutor
import javax.inject.Inject import javax.inject.Inject
@@ -72,7 +75,8 @@ private fun PlaybackState.computePosition(duration: Long): Long {
/** ViewModel for seek bar in QS media player. */ /** ViewModel for seek bar in QS media player. */
class SeekBarViewModel @Inject constructor( 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) private var _data = Progress(false, false, false, false, null, 0)
set(value) { set(value) {
@@ -275,7 +279,7 @@ class SeekBarViewModel @Inject constructor(
/** Gets a listener to attach to the seek bar to handle seeking. */ /** Gets a listener to attach to the seek bar to handle seeking. */
val seekBarListener: SeekBar.OnSeekBarChangeListener val seekBarListener: SeekBar.OnSeekBarChangeListener
get() { get() {
return SeekBarChangeListener(this) return SeekBarChangeListener(this, falsingManager)
} }
/** Attach touch handlers to the seek bar view. */ /** Attach touch handlers to the seek bar view. */
@@ -315,7 +319,8 @@ class SeekBarViewModel @Inject constructor(
} }
private class SeekBarChangeListener( private class SeekBarChangeListener(
val viewModel: SeekBarViewModel val viewModel: SeekBarViewModel,
val falsingManager: FalsingManager,
) : SeekBar.OnSeekBarChangeListener { ) : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(bar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(bar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
@@ -328,6 +333,13 @@ class SeekBarViewModel @Inject constructor(
} }
override fun onStopTrackingTouch(bar: SeekBar) { 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()) viewModel.onSeek(bar.progress.toLong())
} }
} }
@@ -340,7 +352,7 @@ class SeekBarViewModel @Inject constructor(
*/ */
private class SeekBarTouchListener( private class SeekBarTouchListener(
private val viewModel: SeekBarViewModel, private val viewModel: SeekBarViewModel,
private val bar: SeekBar private val bar: SeekBar,
) : View.OnTouchListener, GestureDetector.OnGestureListener { ) : View.OnTouchListener, GestureDetector.OnGestureListener {
// Gesture detector helps decide which touch events to intercept. // 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.ArchTaskExecutor
import androidx.arch.core.executor.TaskExecutor import androidx.arch.core.executor.TaskExecutor
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase 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.FakeExecutor
import com.android.systemui.util.concurrency.FakeRepeatableExecutor import com.android.systemui.util.concurrency.FakeRepeatableExecutor
import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Ignore import org.junit.Ignore
@@ -47,8 +47,8 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.never import org.mockito.Mockito.never
import org.mockito.Mockito.times import org.mockito.Mockito.times
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner::class) @RunWith(AndroidTestingRunner::class)
@@ -70,6 +70,8 @@ public class SeekBarViewModelTest : SysuiTestCase() {
} }
@Mock private lateinit var mockController: MediaController @Mock private lateinit var mockController: MediaController
@Mock private lateinit var mockTransport: MediaController.TransportControls @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 token1 = MediaSession.Token(1, null)
private val token2 = MediaSession.Token(2, null) private val token2 = MediaSession.Token(2, null)
@@ -78,9 +80,10 @@ public class SeekBarViewModelTest : SysuiTestCase() {
@Before @Before
fun setUp() { fun setUp() {
fakeExecutor = FakeExecutor(FakeSystemClock()) fakeExecutor = FakeExecutor(FakeSystemClock())
viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor)) viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor), falsingManager)
viewModel.logSeek = { } viewModel.logSeek = { }
whenever(mockController.sessionToken).thenReturn(token1) whenever(mockController.sessionToken).thenReturn(token1)
whenever(mockBar.context).thenReturn(context)
// LiveData to run synchronously // LiveData to run synchronously
ArchTaskExecutor.getInstance().setDelegate(taskExecutor) ArchTaskExecutor.getInstance().setDelegate(taskExecutor)
@@ -453,6 +456,25 @@ public class SeekBarViewModelTest : SysuiTestCase() {
verify(mockTransport).seekTo(eq(pos.toLong())) 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 @Test
fun queuePollTaskWhenPlaying() { fun queuePollTaskWhenPlaying() {
// GIVEN that the track is playing // GIVEN that the track is playing