• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2010 The Android Open Source Project
3 //
4 
5 #include <ui/InputDispatcher.h>
6 #include <gtest/gtest.h>
7 #include <linux/input.h>
8 
9 namespace android {
10 
11 // An arbitrary time value.
12 static const nsecs_t ARBITRARY_TIME = 1234;
13 
14 // An arbitrary device id.
15 static const int32_t DEVICE_ID = 1;
16 
17 // An arbitrary injector pid / uid pair that has permission to inject events.
18 static const int32_t INJECTOR_PID = 999;
19 static const int32_t INJECTOR_UID = 1001;
20 
21 
22 // --- FakeInputDispatcherPolicy ---
23 
24 class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
25 protected:
~FakeInputDispatcherPolicy()26     virtual ~FakeInputDispatcherPolicy() {
27     }
28 
29 public:
FakeInputDispatcherPolicy()30     FakeInputDispatcherPolicy() {
31     }
32 
33 private:
notifyConfigurationChanged(nsecs_t when)34     virtual void notifyConfigurationChanged(nsecs_t when) {
35     }
36 
notifyANR(const sp<InputApplicationHandle> & inputApplicationHandle,const sp<InputChannel> & inputChannel)37     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
38             const sp<InputChannel>& inputChannel) {
39         return 0;
40     }
41 
notifyInputChannelBroken(const sp<InputChannel> & inputChannel)42     virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
43     }
44 
getKeyRepeatTimeout()45     virtual nsecs_t getKeyRepeatTimeout() {
46         return 500 * 1000000LL;
47     }
48 
getKeyRepeatDelay()49     virtual nsecs_t getKeyRepeatDelay() {
50         return 50 * 1000000LL;
51     }
52 
getMaxEventsPerSecond()53     virtual int32_t getMaxEventsPerSecond() {
54         return 60;
55     }
56 
interceptKeyBeforeQueueing(nsecs_t when,int32_t deviceId,int32_t action,int32_t & flags,int32_t keyCode,int32_t scanCode,uint32_t & policyFlags)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 
interceptGenericBeforeQueueing(nsecs_t when,uint32_t & policyFlags)62     virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
63     }
64 
interceptKeyBeforeDispatching(const sp<InputChannel> & inputChannel,const KeyEvent * keyEvent,uint32_t policyFlags)65     virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
66             const KeyEvent* keyEvent, uint32_t policyFlags) {
67         return false;
68     }
69 
notifySwitch(nsecs_t when,int32_t switchCode,int32_t switchValue,uint32_t policyFlags)70     virtual void notifySwitch(nsecs_t when,
71             int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
72     }
73 
pokeUserActivity(nsecs_t eventTime,int32_t eventType)74     virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
75     }
76 
checkInjectEventsPermissionNonReentrant(int32_t injectorPid,int32_t injectorUid)77     virtual bool checkInjectEventsPermissionNonReentrant(
78             int32_t injectorPid, int32_t injectorUid) {
79         return false;
80     }
81 };
82 
83 
84 // --- InputDispatcherTest ---
85 
86 class InputDispatcherTest : public testing::Test {
87 protected:
88     sp<FakeInputDispatcherPolicy> mFakePolicy;
89     sp<InputDispatcher> mDispatcher;
90 
SetUp()91     virtual void SetUp() {
92         mFakePolicy = new FakeInputDispatcherPolicy();
93         mDispatcher = new InputDispatcher(mFakePolicy);
94     }
95 
TearDown()96     virtual void TearDown() {
97         mFakePolicy.clear();
98         mDispatcher.clear();
99     }
100 };
101 
102 
TEST_F(InputDispatcherTest,InjectInputEvent_ValidatesKeyEvents)103 TEST_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 
TEST_F(InputDispatcherTest,InjectInputEvent_ValidatesMotionEvents)123 TEST_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.";
224 }
225 
226 } // namespace android
227