blob: fc89a9b189056dc64ece0952e283ee3f966537d4 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "../InputDispatcher.h"
18
19#include <gtest/gtest.h>
20#include <linux/input.h>
21
22namespace android {
23
24// An arbitrary time value.
25static const nsecs_t ARBITRARY_TIME = 1234;
26
27// An arbitrary device id.
28static const int32_t DEVICE_ID = 1;
29
Jeff Brownf086ddb2014-02-11 14:28:48 -080030// An arbitrary display id.
31static const int32_t DISPLAY_ID = 0;
32
Michael Wrightd02c5b62014-02-10 15:10:22 -080033// An arbitrary injector pid / uid pair that has permission to inject events.
34static const int32_t INJECTOR_PID = 999;
35static const int32_t INJECTOR_UID = 1001;
36
37
38// --- FakeInputDispatcherPolicy ---
39
40class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
41 InputDispatcherConfiguration mConfig;
42
43protected:
44 virtual ~FakeInputDispatcherPolicy() {
45 }
46
47public:
48 FakeInputDispatcherPolicy() {
49 }
50
51private:
52 virtual void notifyConfigurationChanged(nsecs_t when) {
53 }
54
55 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
56 const sp<InputWindowHandle>& inputWindowHandle,
57 const String8& reason) {
58 return 0;
59 }
60
61 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
62 }
63
64 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
65 *outConfig = mConfig;
66 }
67
68 virtual bool isKeyRepeatEnabled() {
69 return true;
70 }
71
72 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
73 return true;
74 }
75
76 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
77 }
78
79 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
80 }
81
82 virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
83 const KeyEvent* keyEvent, uint32_t policyFlags) {
84 return 0;
85 }
86
87 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
88 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
89 return false;
90 }
91
92 virtual void notifySwitch(nsecs_t when,
93 uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) {
94 }
95
96 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
97 }
98
99 virtual bool checkInjectEventsPermissionNonReentrant(
100 int32_t injectorPid, int32_t injectorUid) {
101 return false;
102 }
103};
104
105
106// --- InputDispatcherTest ---
107
108class InputDispatcherTest : public testing::Test {
109protected:
110 sp<FakeInputDispatcherPolicy> mFakePolicy;
111 sp<InputDispatcher> mDispatcher;
112
113 virtual void SetUp() {
114 mFakePolicy = new FakeInputDispatcherPolicy();
115 mDispatcher = new InputDispatcher(mFakePolicy);
116 }
117
118 virtual void TearDown() {
119 mFakePolicy.clear();
120 mDispatcher.clear();
121 }
122};
123
124
125TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
126 KeyEvent event;
127
128 // Rejects undefined key actions.
129 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
130 /*action*/ -1, 0,
131 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800132 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
133 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
135 << "Should reject key events with undefined action.";
136
137 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
138 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
139 AKEY_EVENT_ACTION_MULTIPLE, 0,
140 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800141 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
142 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800143 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
144 << "Should reject key events with ACTION_MULTIPLE.";
145}
146
147TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
148 MotionEvent event;
149 PointerProperties pointerProperties[MAX_POINTERS + 1];
150 PointerCoords pointerCoords[MAX_POINTERS + 1];
151 for (int i = 0; i <= MAX_POINTERS; i++) {
152 pointerProperties[i].clear();
153 pointerProperties[i].id = i;
154 pointerCoords[i].clear();
155 }
156
157 // Rejects undefined motion actions.
158 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
159 /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
160 ARBITRARY_TIME, ARBITRARY_TIME,
161 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800162 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
163 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
165 << "Should reject motion events with undefined action.";
166
167 // Rejects pointer down with invalid index.
168 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
169 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
170 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
171 ARBITRARY_TIME, ARBITRARY_TIME,
172 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800173 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
174 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
176 << "Should reject motion events with pointer down index too large.";
177
178 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
179 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
180 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
181 ARBITRARY_TIME, ARBITRARY_TIME,
182 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800183 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
184 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
186 << "Should reject motion events with pointer down index too small.";
187
188 // Rejects pointer up with invalid index.
189 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
190 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
191 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
192 ARBITRARY_TIME, ARBITRARY_TIME,
193 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800194 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
195 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
197 << "Should reject motion events with pointer up index too large.";
198
199 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
200 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
201 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
202 ARBITRARY_TIME, ARBITRARY_TIME,
203 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800204 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
205 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
207 << "Should reject motion events with pointer up index too small.";
208
209 // Rejects motion events with invalid number of pointers.
210 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
211 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
212 ARBITRARY_TIME, ARBITRARY_TIME,
213 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800214 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
215 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
217 << "Should reject motion events with 0 pointers.";
218
219 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
220 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
221 ARBITRARY_TIME, ARBITRARY_TIME,
222 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800223 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
224 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
226 << "Should reject motion events with more than MAX_POINTERS pointers.";
227
228 // Rejects motion events with invalid pointer ids.
229 pointerProperties[0].id = -1;
230 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
231 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
232 ARBITRARY_TIME, ARBITRARY_TIME,
233 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800234 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
235 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
237 << "Should reject motion events with pointer ids less than 0.";
238
239 pointerProperties[0].id = MAX_POINTER_ID + 1;
240 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
241 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
242 ARBITRARY_TIME, ARBITRARY_TIME,
243 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800244 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
245 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
247 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
248
249 // Rejects motion events with duplicate pointer ids.
250 pointerProperties[0].id = 1;
251 pointerProperties[1].id = 1;
252 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
253 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
254 ARBITRARY_TIME, ARBITRARY_TIME,
255 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800256 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
257 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
259 << "Should reject motion events with duplicate pointer ids.";
260}
261
262} // namespace android