blob: 7aac6edfe1984a42618adf22462e804be481f2c2 [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
Michael Wrightd02c5b62014-02-10 15:10:22 -080068 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
69 return true;
70 }
71
72 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
73 }
74
75 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
76 }
77
78 virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
79 const KeyEvent* keyEvent, uint32_t policyFlags) {
80 return 0;
81 }
82
83 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
84 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
85 return false;
86 }
87
88 virtual void notifySwitch(nsecs_t when,
89 uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) {
90 }
91
92 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
93 }
94
95 virtual bool checkInjectEventsPermissionNonReentrant(
96 int32_t injectorPid, int32_t injectorUid) {
97 return false;
98 }
99};
100
101
102// --- InputDispatcherTest ---
103
104class InputDispatcherTest : public testing::Test {
105protected:
106 sp<FakeInputDispatcherPolicy> mFakePolicy;
107 sp<InputDispatcher> mDispatcher;
108
109 virtual void SetUp() {
110 mFakePolicy = new FakeInputDispatcherPolicy();
111 mDispatcher = new InputDispatcher(mFakePolicy);
112 }
113
114 virtual void TearDown() {
115 mFakePolicy.clear();
116 mDispatcher.clear();
117 }
118};
119
120
121TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
122 KeyEvent event;
123
124 // Rejects undefined key actions.
125 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
126 /*action*/ -1, 0,
127 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800128 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
129 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800130 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
131 << "Should reject key events with undefined action.";
132
133 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
134 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
135 AKEY_EVENT_ACTION_MULTIPLE, 0,
136 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800137 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
138 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
140 << "Should reject key events with ACTION_MULTIPLE.";
141}
142
143TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
144 MotionEvent event;
145 PointerProperties pointerProperties[MAX_POINTERS + 1];
146 PointerCoords pointerCoords[MAX_POINTERS + 1];
147 for (int i = 0; i <= MAX_POINTERS; i++) {
148 pointerProperties[i].clear();
149 pointerProperties[i].id = i;
150 pointerCoords[i].clear();
151 }
152
153 // Rejects undefined motion actions.
154 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
155 /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
156 ARBITRARY_TIME, ARBITRARY_TIME,
157 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800158 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
159 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800160 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
161 << "Should reject motion events with undefined action.";
162
163 // Rejects pointer down with invalid index.
164 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
165 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
166 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
167 ARBITRARY_TIME, ARBITRARY_TIME,
168 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800169 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
170 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
172 << "Should reject motion events with pointer down index too large.";
173
174 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
175 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
176 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
177 ARBITRARY_TIME, ARBITRARY_TIME,
178 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800179 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
180 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
182 << "Should reject motion events with pointer down index too small.";
183
184 // Rejects pointer up with invalid index.
185 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
186 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
187 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
188 ARBITRARY_TIME, ARBITRARY_TIME,
189 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800190 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
191 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
193 << "Should reject motion events with pointer up index too large.";
194
195 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
196 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
197 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
198 ARBITRARY_TIME, ARBITRARY_TIME,
199 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800200 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
201 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
203 << "Should reject motion events with pointer up index too small.";
204
205 // Rejects motion events with invalid number of pointers.
206 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
207 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
208 ARBITRARY_TIME, ARBITRARY_TIME,
209 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800210 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
211 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
213 << "Should reject motion events with 0 pointers.";
214
215 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
216 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
217 ARBITRARY_TIME, ARBITRARY_TIME,
218 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800219 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
220 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
222 << "Should reject motion events with more than MAX_POINTERS pointers.";
223
224 // Rejects motion events with invalid pointer ids.
225 pointerProperties[0].id = -1;
226 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
227 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
228 ARBITRARY_TIME, ARBITRARY_TIME,
229 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800230 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
231 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
233 << "Should reject motion events with pointer ids less than 0.";
234
235 pointerProperties[0].id = MAX_POINTER_ID + 1;
236 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
237 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
238 ARBITRARY_TIME, ARBITRARY_TIME,
239 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800240 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
241 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
243 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
244
245 // Rejects motion events with duplicate pointer ids.
246 pointerProperties[0].id = 1;
247 pointerProperties[1].id = 1;
248 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
249 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
250 ARBITRARY_TIME, ARBITRARY_TIME,
251 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800252 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
253 &event, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
255 << "Should reject motion events with duplicate pointer ids.";
256}
257
258} // namespace android