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