blob: f352dbf6afab14de343c266e32e6c09b181a64ac [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4
5#include <ui/InputDispatcher.h>
6#include <gtest/gtest.h>
Jeff Brown3c3cc622010-10-20 15:33:38 -07007#include <linux/input.h>
Jeff Browne839a582010-04-22 18:58:52 -07008
9namespace android {
10
Jeff Brown3c3cc622010-10-20 15:33:38 -070011// An arbitrary time value.
12static const nsecs_t ARBITRARY_TIME = 1234;
13
14// An arbitrary device id.
15static const int32_t DEVICE_ID = 1;
16
17// An arbitrary injector pid / uid pair that has permission to inject events.
18static const int32_t INJECTOR_PID = 999;
19static const int32_t INJECTOR_UID = 1001;
20
21
22// --- FakeInputDispatcherPolicy ---
23
24class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
25protected:
26 virtual ~FakeInputDispatcherPolicy() {
27 }
28
Jeff Browne839a582010-04-22 18:58:52 -070029public:
Jeff Brown3c3cc622010-10-20 15:33:38 -070030 FakeInputDispatcherPolicy() {
31 }
32
33private:
34 virtual void notifyConfigurationChanged(nsecs_t when) {
35 }
36
37 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
38 const sp<InputChannel>& inputChannel) {
39 return 0;
40 }
41
42 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
43 }
44
45 virtual nsecs_t getKeyRepeatTimeout() {
46 return 500 * 1000000LL;
47 }
48
49 virtual nsecs_t getKeyRepeatDelay() {
50 return 50 * 1000000LL;
51 }
52
53 virtual int32_t getMaxEventsPerSecond() {
54 return 60;
55 }
56
57 virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
58 int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
59 uint32_t& policyFlags) {
60 }
61
62 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
63 }
64
65 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
66 const KeyEvent* keyEvent, uint32_t policyFlags) {
67 return false;
68 }
69
Jeff Brown81499912010-11-05 15:02:16 -070070 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
71 const KeyEvent* keyEvent, uint32_t policyFlags) {
72 return false;
73 }
74
Jeff Brown3c3cc622010-10-20 15:33:38 -070075 virtual void notifySwitch(nsecs_t when,
76 int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
77 }
78
79 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
80 }
81
82 virtual bool checkInjectEventsPermissionNonReentrant(
83 int32_t injectorPid, int32_t injectorUid) {
84 return false;
85 }
Jeff Browne839a582010-04-22 18:58:52 -070086};
87
Jeff Brown3c3cc622010-10-20 15:33:38 -070088
89// --- InputDispatcherTest ---
90
91class InputDispatcherTest : public testing::Test {
92protected:
93 sp<FakeInputDispatcherPolicy> mFakePolicy;
94 sp<InputDispatcher> mDispatcher;
95
96 virtual void SetUp() {
97 mFakePolicy = new FakeInputDispatcherPolicy();
98 mDispatcher = new InputDispatcher(mFakePolicy);
99 }
100
101 virtual void TearDown() {
102 mFakePolicy.clear();
103 mDispatcher.clear();
104 }
105};
106
107
108TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
109 KeyEvent event;
110
111 // Rejects undefined key actions.
112 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
113 /*action*/ -1, 0,
114 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
115 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
116 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
117 << "Should reject key events with undefined action.";
118
119 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
120 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
121 AKEY_EVENT_ACTION_MULTIPLE, 0,
122 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
123 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
124 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
125 << "Should reject key events with ACTION_MULTIPLE.";
126}
127
128TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
129 MotionEvent event;
130 int32_t pointerIds[MAX_POINTERS + 1];
131 PointerCoords pointerCoords[MAX_POINTERS + 1];
132 for (int i = 0; i <= MAX_POINTERS; i++) {
133 pointerIds[i] = i;
134 }
135
136 // Rejects undefined motion actions.
137 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
138 /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0,
139 ARBITRARY_TIME, ARBITRARY_TIME,
140 /*pointerCount*/ 1, pointerIds, pointerCoords);
141 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
142 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
143 << "Should reject motion events with undefined action.";
144
145 // Rejects pointer down with invalid index.
146 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
147 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
148 0, 0, AMETA_NONE, 0, 0, 0, 0,
149 ARBITRARY_TIME, ARBITRARY_TIME,
150 /*pointerCount*/ 1, pointerIds, pointerCoords);
151 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
152 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
153 << "Should reject motion events with pointer down index too large.";
154
155 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
156 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
157 0, 0, AMETA_NONE, 0, 0, 0, 0,
158 ARBITRARY_TIME, ARBITRARY_TIME,
159 /*pointerCount*/ 1, pointerIds, pointerCoords);
160 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
161 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
162 << "Should reject motion events with pointer down index too small.";
163
164 // Rejects pointer up with invalid index.
165 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
166 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
167 0, 0, AMETA_NONE, 0, 0, 0, 0,
168 ARBITRARY_TIME, ARBITRARY_TIME,
169 /*pointerCount*/ 1, pointerIds, pointerCoords);
170 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
171 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
172 << "Should reject motion events with pointer up index too large.";
173
174 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
175 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
176 0, 0, AMETA_NONE, 0, 0, 0, 0,
177 ARBITRARY_TIME, ARBITRARY_TIME,
178 /*pointerCount*/ 1, pointerIds, pointerCoords);
179 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
180 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
181 << "Should reject motion events with pointer up index too small.";
182
183 // Rejects motion events with invalid number of pointers.
184 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
185 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
186 ARBITRARY_TIME, ARBITRARY_TIME,
187 /*pointerCount*/ 0, pointerIds, pointerCoords);
188 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
189 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
190 << "Should reject motion events with 0 pointers.";
191
192 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
193 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
194 ARBITRARY_TIME, ARBITRARY_TIME,
195 /*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords);
196 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
197 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
198 << "Should reject motion events with more than MAX_POINTERS pointers.";
199
200 // Rejects motion events with invalid pointer ids.
201 pointerIds[0] = -1;
202 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
203 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
204 ARBITRARY_TIME, ARBITRARY_TIME,
205 /*pointerCount*/ 1, pointerIds, pointerCoords);
206 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
207 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
208 << "Should reject motion events with pointer ids less than 0.";
209
210 pointerIds[0] = MAX_POINTER_ID + 1;
211 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
212 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
213 ARBITRARY_TIME, ARBITRARY_TIME,
214 /*pointerCount*/ 1, pointerIds, pointerCoords);
215 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
216 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
217 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
218
219 // Rejects motion events with duplicate pointer ids.
220 pointerIds[0] = 1;
221 pointerIds[1] = 1;
222 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
223 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
224 ARBITRARY_TIME, ARBITRARY_TIME,
225 /*pointerCount*/ 2, pointerIds, pointerCoords);
226 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
227 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
228 << "Should reject motion events with duplicate pointer ids.";
Jeff Browne839a582010-04-22 18:58:52 -0700229}
230
231} // namespace android