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