package com.android.systemui.statusbar.gesture import android.testing.TestableLooper import android.view.InputEvent import android.view.MotionEvent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.FakeDisplayTracker import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class GenericGestureDetectorTest : SysuiTestCase() { private lateinit var gestureDetector: TestGestureDetector private lateinit var displayTracker: FakeDisplayTracker @Before fun setUp() { displayTracker = FakeDisplayTracker(mContext) gestureDetector = TestGestureDetector() } @Test fun noCallbacksRegistered_notGestureListening() { assertThat(gestureDetector.isGestureListening).isFalse() } @Test fun callbackRegistered_isGestureListening() { gestureDetector.addOnGestureDetectedCallback("tag") {} assertThat(gestureDetector.isGestureListening).isTrue() } @Test fun multipleCallbacksRegistered_isGestureListening() { gestureDetector.addOnGestureDetectedCallback("tag") {} gestureDetector.addOnGestureDetectedCallback("tag2") {} assertThat(gestureDetector.isGestureListening).isTrue() } @Test fun allCallbacksUnregistered_notGestureListening() { gestureDetector.addOnGestureDetectedCallback("tag") {} gestureDetector.addOnGestureDetectedCallback("tag2") {} gestureDetector.removeOnGestureDetectedCallback("tag") gestureDetector.removeOnGestureDetectedCallback("tag2") assertThat(gestureDetector.isGestureListening).isFalse() } @Test fun someButNotAllCallbacksUnregistered_isGestureListening() { gestureDetector.addOnGestureDetectedCallback("tag") {} gestureDetector.addOnGestureDetectedCallback("tag2") {} gestureDetector.removeOnGestureDetectedCallback("tag2") assertThat(gestureDetector.isGestureListening).isTrue() } @Test fun onInputEvent_meetsGestureCriteria_allCallbacksNotified() { var callbackNotified = false gestureDetector.addOnGestureDetectedCallback("tag") { callbackNotified = true } gestureDetector.onInputEvent( MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0) ) assertThat(callbackNotified).isTrue() } @Test fun onInputEvent_doesNotMeetGestureCriteria_callbackNotNotified() { var callbackNotified = false gestureDetector.addOnGestureDetectedCallback("tag") { callbackNotified = true } gestureDetector.onInputEvent( MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X - 5, 0f, 0) ) assertThat(callbackNotified).isFalse() } @Test fun callbackUnregisteredThenGestureDetected_oldCallbackNotNotified() { var oldCallbackNotified = false gestureDetector.addOnGestureDetectedCallback("tag") { oldCallbackNotified = true } gestureDetector.addOnGestureDetectedCallback("tag2") {} gestureDetector.removeOnGestureDetectedCallback("tag") gestureDetector.onInputEvent( MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0) ) assertThat(oldCallbackNotified).isFalse() } inner class TestGestureDetector : GenericGestureDetector("fakeTag", displayTracker.defaultDisplayId) { var isGestureListening = false override fun onInputEvent(ev: InputEvent) { if (ev is MotionEvent && ev.x == CORRECT_X) { onGestureDetected(ev) } } override fun startGestureListening() { super.startGestureListening() isGestureListening = true } override fun stopGestureListening() { super.stopGestureListening() isGestureListening = false } } } private const val CORRECT_X = 1234f