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