• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.test.input
18 
19 import android.view.InputDevice.SOURCE_MOUSE
20 import android.view.InputDevice.SOURCE_TOUCHSCREEN
21 import android.view.InputEventAssigner
22 import android.view.KeyEvent
23 import android.view.MotionEvent
24 import org.junit.Assert.assertEquals
25 import org.junit.Test
26 
27 /**
28  * Create a MotionEvent with the provided action, eventTime, and source
29  */
createMotionEventnull30 fun createMotionEvent(action: Int, eventTime: Long, source: Int): MotionEvent {
31     val downTime: Long = 10
32     val x = 1f
33     val y = 2f
34     val pressure = 3f
35     val size = 1f
36     val metaState = 0
37     val xPrecision = 0f
38     val yPrecision = 0f
39     val deviceId = 1
40     val edgeFlags = 0
41     val displayId = 0
42     return MotionEvent.obtain(downTime, eventTime, action, x, y, pressure, size, metaState,
43             xPrecision, yPrecision, deviceId, edgeFlags, source, displayId)
44 }
45 
createKeyEventnull46 private fun createKeyEvent(action: Int, eventTime: Long): KeyEvent {
47     val code = KeyEvent.KEYCODE_A
48     val repeat = 0
49     return KeyEvent(eventTime, eventTime, action, code, repeat)
50 }
51 
52 class InputEventAssignerTest {
53     companion object {
54         private const val TAG = "InputEventAssignerTest"
55     }
56 
57     /**
58      * A single MOVE event should be assigned to the next available frame.
59      */
60     @Test
testTouchGesturenull61     fun testTouchGesture() {
62         val assigner = InputEventAssigner()
63         val event = createMotionEvent(MotionEvent.ACTION_MOVE, 10, SOURCE_TOUCHSCREEN)
64         val eventId = assigner.processEvent(event)
65         assertEquals(event.id, eventId)
66     }
67 
68     /**
69      * DOWN event should be used until a vsync comes in. After vsync, the latest event should be
70      * produced.
71      */
72     @Test
testTouchDownWithMovenull73     fun testTouchDownWithMove() {
74         val assigner = InputEventAssigner()
75         val down = createMotionEvent(MotionEvent.ACTION_DOWN, 10, SOURCE_TOUCHSCREEN)
76         val move1 = createMotionEvent(MotionEvent.ACTION_MOVE, 12, SOURCE_TOUCHSCREEN)
77         val move2 = createMotionEvent(MotionEvent.ACTION_MOVE, 13, SOURCE_TOUCHSCREEN)
78         val move3 = createMotionEvent(MotionEvent.ACTION_MOVE, 14, SOURCE_TOUCHSCREEN)
79         val move4 = createMotionEvent(MotionEvent.ACTION_MOVE, 15, SOURCE_TOUCHSCREEN)
80         var eventId = assigner.processEvent(down)
81         assertEquals(down.id, eventId)
82         eventId = assigner.processEvent(move1)
83         assertEquals(down.id, eventId)
84         eventId = assigner.processEvent(move2)
85         // Even though we already had 2 move events, there was no choreographer callback yet.
86         // Therefore, we should still get the id of the down event
87         assertEquals(down.id, eventId)
88 
89         // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event
90         assigner.notifyFrameProcessed()
91         eventId = assigner.processEvent(move3)
92         assertEquals(move3.id, eventId)
93         eventId = assigner.processEvent(move4)
94         assertEquals(move4.id, eventId)
95     }
96 
97     /**
98      * Similar to the above test, but with SOURCE_MOUSE. Since we don't have down latency
99      * concept for non-touchscreens, the latest input event will be used.
100      */
101     @Test
testMouseDownWithMovenull102     fun testMouseDownWithMove() {
103         val assigner = InputEventAssigner()
104         val down = createMotionEvent(MotionEvent.ACTION_DOWN, 10, SOURCE_MOUSE)
105         val move1 = createMotionEvent(MotionEvent.ACTION_MOVE, 12, SOURCE_MOUSE)
106         var eventId = assigner.processEvent(down)
107         assertEquals(down.id, eventId)
108         eventId = assigner.processEvent(move1)
109         assertEquals(move1.id, eventId)
110     }
111 
112     /**
113      * KeyEvents are processed immediately, so the latest event should be returned.
114      */
115     @Test
testKeyEventnull116     fun testKeyEvent() {
117         val assigner = InputEventAssigner()
118         val down = createKeyEvent(KeyEvent.ACTION_DOWN, 20)
119         var eventId = assigner.processEvent(down)
120         assertEquals(down.id, eventId)
121         val up = createKeyEvent(KeyEvent.ACTION_UP, 21)
122         eventId = assigner.processEvent(up)
123         // DOWN is only sticky for Motions, not for keys
124         assertEquals(up.id, eventId)
125         assigner.notifyFrameProcessed()
126         val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22)
127         eventId = assigner.processEvent(down2)
128         assertEquals(down2.id, eventId)
129     }
130 }
131