1 package com.android.systemui.statusbar.gesture 2 3 import android.testing.AndroidTestingRunner 4 import android.testing.TestableLooper 5 import android.view.InputEvent 6 import android.view.MotionEvent 7 import androidx.test.filters.SmallTest 8 import com.android.systemui.SysuiTestCase 9 import com.android.systemui.settings.FakeDisplayTracker 10 import com.google.common.truth.Truth.assertThat 11 import org.junit.Before 12 import org.junit.Test 13 import org.junit.runner.RunWith 14 15 @SmallTest 16 @RunWith(AndroidTestingRunner::class) 17 @TestableLooper.RunWithLooper 18 class GenericGestureDetectorTest : SysuiTestCase() { 19 20 private lateinit var gestureDetector: TestGestureDetector 21 private lateinit var displayTracker: FakeDisplayTracker 22 23 @Before 24 fun setUp() { 25 displayTracker = FakeDisplayTracker(mContext) 26 gestureDetector = TestGestureDetector() 27 } 28 29 @Test 30 fun noCallbacksRegistered_notGestureListening() { 31 assertThat(gestureDetector.isGestureListening).isFalse() 32 } 33 34 @Test 35 fun callbackRegistered_isGestureListening() { 36 gestureDetector.addOnGestureDetectedCallback("tag"){} 37 38 assertThat(gestureDetector.isGestureListening).isTrue() 39 } 40 41 @Test 42 fun multipleCallbacksRegistered_isGestureListening() { 43 gestureDetector.addOnGestureDetectedCallback("tag"){} 44 gestureDetector.addOnGestureDetectedCallback("tag2"){} 45 46 assertThat(gestureDetector.isGestureListening).isTrue() 47 } 48 49 @Test 50 fun allCallbacksUnregistered_notGestureListening() { 51 gestureDetector.addOnGestureDetectedCallback("tag"){} 52 gestureDetector.addOnGestureDetectedCallback("tag2"){} 53 54 gestureDetector.removeOnGestureDetectedCallback("tag") 55 gestureDetector.removeOnGestureDetectedCallback("tag2") 56 57 assertThat(gestureDetector.isGestureListening).isFalse() 58 } 59 60 @Test 61 fun someButNotAllCallbacksUnregistered_isGestureListening() { 62 gestureDetector.addOnGestureDetectedCallback("tag"){} 63 gestureDetector.addOnGestureDetectedCallback("tag2"){} 64 65 gestureDetector.removeOnGestureDetectedCallback("tag2") 66 67 assertThat(gestureDetector.isGestureListening).isTrue() 68 } 69 70 @Test 71 fun onInputEvent_meetsGestureCriteria_allCallbacksNotified() { 72 var callbackNotified = false 73 gestureDetector.addOnGestureDetectedCallback("tag"){ 74 callbackNotified = true 75 } 76 77 gestureDetector.onInputEvent( 78 MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0) 79 ) 80 81 assertThat(callbackNotified).isTrue() 82 } 83 84 @Test 85 fun onInputEvent_doesNotMeetGestureCriteria_callbackNotNotified() { 86 var callbackNotified = false 87 gestureDetector.addOnGestureDetectedCallback("tag"){ 88 callbackNotified = true 89 } 90 91 gestureDetector.onInputEvent( 92 MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X - 5, 0f, 0) 93 ) 94 95 assertThat(callbackNotified).isFalse() 96 } 97 98 @Test 99 fun callbackUnregisteredThenGestureDetected_oldCallbackNotNotified() { 100 var oldCallbackNotified = false 101 gestureDetector.addOnGestureDetectedCallback("tag"){ 102 oldCallbackNotified = true 103 } 104 gestureDetector.addOnGestureDetectedCallback("tag2"){} 105 106 gestureDetector.removeOnGestureDetectedCallback("tag") 107 gestureDetector.onInputEvent( 108 MotionEvent.obtain( 109 0, 110 0, 111 MotionEvent.ACTION_DOWN, 112 CORRECT_X, 113 0f, 114 0 115 ) 116 ) 117 118 assertThat(oldCallbackNotified).isFalse() 119 } 120 121 inner class TestGestureDetector : GenericGestureDetector( 122 "fakeTag", 123 displayTracker.defaultDisplayId 124 ) { 125 var isGestureListening = false 126 127 override fun onInputEvent(ev: InputEvent) { 128 if (ev is MotionEvent && ev.x == CORRECT_X) { 129 onGestureDetected(ev) 130 } 131 } 132 133 override fun startGestureListening() { 134 super.startGestureListening() 135 isGestureListening = true 136 } 137 138 override fun stopGestureListening() { 139 super.stopGestureListening() 140 isGestureListening = false 141 } 142 } 143 } 144 145 private const val CORRECT_X = 1234f 146