blob: 7e17c57a9227f8449e83611b9284737ca8ac3e67 [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
Jeff Brown53c16642010-11-18 20:53:46 -080057 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
Jeff Brown3c3cc622010-10-20 15:33:38 -070058 }
59
60 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
61 }
62
63 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
64 const KeyEvent* keyEvent, uint32_t policyFlags) {
65 return false;
66 }
67
Jeff Brown81499912010-11-05 15:02:16 -070068 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown02d85b52010-12-06 17:13:33 -080069 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown81499912010-11-05 15:02:16 -070070 return false;
71 }
72
Jeff Brown3c3cc622010-10-20 15:33:38 -070073 virtual void notifySwitch(nsecs_t when,
74 int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
75 }
76
77 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
78 }
79
80 virtual bool checkInjectEventsPermissionNonReentrant(
81 int32_t injectorPid, int32_t injectorUid) {
82 return false;
83 }
Jeff Browne839a582010-04-22 18:58:52 -070084};
85
Jeff Brown3c3cc622010-10-20 15:33:38 -070086
87// --- InputDispatcherTest ---
88
89class InputDispatcherTest : public testing::Test {
90protected:
91 sp<FakeInputDispatcherPolicy> mFakePolicy;
92 sp<InputDispatcher> mDispatcher;
93
94 virtual void SetUp() {
95 mFakePolicy = new FakeInputDispatcherPolicy();
96 mDispatcher = new InputDispatcher(mFakePolicy);
97 }
98
99 virtual void TearDown() {
100 mFakePolicy.clear();
101 mDispatcher.clear();
102 }
103};
104
105
106TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
107 KeyEvent event;
108
109 // Rejects undefined key actions.
110 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
111 /*action*/ -1, 0,
112 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
113 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
114 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
115 << "Should reject key events with undefined action.";
116
117 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
118 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
119 AKEY_EVENT_ACTION_MULTIPLE, 0,
120 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
121 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
122 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
123 << "Should reject key events with ACTION_MULTIPLE.";
124}
125
126TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
127 MotionEvent event;
128 int32_t pointerIds[MAX_POINTERS + 1];
129 PointerCoords pointerCoords[MAX_POINTERS + 1];
130 for (int i = 0; i <= MAX_POINTERS; i++) {
131 pointerIds[i] = i;
132 }
133
134 // Rejects undefined motion actions.
135 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
136 /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0,
137 ARBITRARY_TIME, ARBITRARY_TIME,
138 /*pointerCount*/ 1, pointerIds, pointerCoords);
139 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
140 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
141 << "Should reject motion events with undefined action.";
142
143 // Rejects pointer down with invalid index.
144 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
145 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
146 0, 0, AMETA_NONE, 0, 0, 0, 0,
147 ARBITRARY_TIME, ARBITRARY_TIME,
148 /*pointerCount*/ 1, pointerIds, pointerCoords);
149 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
150 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
151 << "Should reject motion events with pointer down index too large.";
152
153 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
154 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
155 0, 0, AMETA_NONE, 0, 0, 0, 0,
156 ARBITRARY_TIME, ARBITRARY_TIME,
157 /*pointerCount*/ 1, pointerIds, pointerCoords);
158 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
159 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
160 << "Should reject motion events with pointer down index too small.";
161
162 // Rejects pointer up with invalid index.
163 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
164 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
165 0, 0, AMETA_NONE, 0, 0, 0, 0,
166 ARBITRARY_TIME, ARBITRARY_TIME,
167 /*pointerCount*/ 1, pointerIds, pointerCoords);
168 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
169 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
170 << "Should reject motion events with pointer up index too large.";
171
172 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
173 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
174 0, 0, AMETA_NONE, 0, 0, 0, 0,
175 ARBITRARY_TIME, ARBITRARY_TIME,
176 /*pointerCount*/ 1, pointerIds, pointerCoords);
177 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
178 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
179 << "Should reject motion events with pointer up index too small.";
180
181 // Rejects motion events with invalid number of pointers.
182 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
183 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
184 ARBITRARY_TIME, ARBITRARY_TIME,
185 /*pointerCount*/ 0, pointerIds, pointerCoords);
186 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
187 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
188 << "Should reject motion events with 0 pointers.";
189
190 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
191 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
192 ARBITRARY_TIME, ARBITRARY_TIME,
193 /*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords);
194 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
195 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
196 << "Should reject motion events with more than MAX_POINTERS pointers.";
197
198 // Rejects motion events with invalid pointer ids.
199 pointerIds[0] = -1;
200 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
201 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
202 ARBITRARY_TIME, ARBITRARY_TIME,
203 /*pointerCount*/ 1, pointerIds, pointerCoords);
204 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
205 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
206 << "Should reject motion events with pointer ids less than 0.";
207
208 pointerIds[0] = MAX_POINTER_ID + 1;
209 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
210 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
211 ARBITRARY_TIME, ARBITRARY_TIME,
212 /*pointerCount*/ 1, pointerIds, pointerCoords);
213 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
214 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
215 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
216
217 // Rejects motion events with duplicate pointer ids.
218 pointerIds[0] = 1;
219 pointerIds[1] = 1;
220 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
221 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
222 ARBITRARY_TIME, ARBITRARY_TIME,
223 /*pointerCount*/ 2, pointerIds, pointerCoords);
224 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
225 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
226 << "Should reject motion events with duplicate pointer ids.";
Jeff Browne839a582010-04-22 18:58:52 -0700227}
228
229} // namespace android