InputDispatcher_test.cpp revision fe9f8ab03a63b1037f07dd85799fbea80ec6adaa
1/* 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 30// An arbitrary injector pid / uid pair that has permission to inject events. 31static const int32_t INJECTOR_PID = 999; 32static const int32_t INJECTOR_UID = 1001; 33 34 35// --- FakeInputDispatcherPolicy --- 36 37class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface { 38protected: 39 virtual ~FakeInputDispatcherPolicy() { 40 } 41 42public: 43 FakeInputDispatcherPolicy() { 44 } 45 46private: 47 virtual void notifyConfigurationChanged(nsecs_t when) { 48 } 49 50 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, 51 const sp<InputWindowHandle>& inputWindowHandle) { 52 return 0; 53 } 54 55 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) { 56 } 57 58 virtual nsecs_t getKeyRepeatTimeout() { 59 return 500 * 1000000LL; 60 } 61 62 virtual nsecs_t getKeyRepeatDelay() { 63 return 50 * 1000000LL; 64 } 65 66 virtual int32_t getMaxEventsPerSecond() { 67 return 60; 68 } 69 70 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) { 71 return true; 72 } 73 74 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) { 75 } 76 77 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) { 78 } 79 80 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, 81 const KeyEvent* keyEvent, uint32_t policyFlags) { 82 return false; 83 } 84 85 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle, 86 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) { 87 return false; 88 } 89 90 virtual void notifySwitch(nsecs_t when, 91 int32_t switchCode, int32_t switchValue, uint32_t policyFlags) { 92 } 93 94 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) { 95 } 96 97 virtual bool checkInjectEventsPermissionNonReentrant( 98 int32_t injectorPid, int32_t injectorUid) { 99 return false; 100 } 101}; 102 103 104// --- InputDispatcherTest --- 105 106class InputDispatcherTest : public testing::Test { 107protected: 108 sp<FakeInputDispatcherPolicy> mFakePolicy; 109 sp<InputDispatcher> mDispatcher; 110 111 virtual void SetUp() { 112 mFakePolicy = new FakeInputDispatcherPolicy(); 113 mDispatcher = new InputDispatcher(mFakePolicy); 114 } 115 116 virtual void TearDown() { 117 mFakePolicy.clear(); 118 mDispatcher.clear(); 119 } 120}; 121 122 123TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { 124 KeyEvent event; 125 126 // Rejects undefined key actions. 127 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, 128 /*action*/ -1, 0, 129 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); 130 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 131 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 132 << "Should reject key events with undefined action."; 133 134 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API. 135 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, 136 AKEY_EVENT_ACTION_MULTIPLE, 0, 137 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); 138 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 139 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); 158 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 159 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 160 << "Should reject motion events with undefined action."; 161 162 // Rejects pointer down with invalid index. 163 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 164 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 165 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 166 ARBITRARY_TIME, ARBITRARY_TIME, 167 /*pointerCount*/ 1, pointerProperties, pointerCoords); 168 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 169 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 170 << "Should reject motion events with pointer down index too large."; 171 172 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 173 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 174 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 175 ARBITRARY_TIME, ARBITRARY_TIME, 176 /*pointerCount*/ 1, pointerProperties, pointerCoords); 177 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 178 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 179 << "Should reject motion events with pointer down index too small."; 180 181 // Rejects pointer up with invalid index. 182 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 183 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 184 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 185 ARBITRARY_TIME, ARBITRARY_TIME, 186 /*pointerCount*/ 1, pointerProperties, pointerCoords); 187 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 188 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 189 << "Should reject motion events with pointer up index too large."; 190 191 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 192 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 193 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 194 ARBITRARY_TIME, ARBITRARY_TIME, 195 /*pointerCount*/ 1, pointerProperties, pointerCoords); 196 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 197 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 198 << "Should reject motion events with pointer up index too small."; 199 200 // Rejects motion events with invalid number of pointers. 201 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 202 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 203 ARBITRARY_TIME, ARBITRARY_TIME, 204 /*pointerCount*/ 0, pointerProperties, pointerCoords); 205 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 206 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 207 << "Should reject motion events with 0 pointers."; 208 209 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 210 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 211 ARBITRARY_TIME, ARBITRARY_TIME, 212 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords); 213 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 214 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 215 << "Should reject motion events with more than MAX_POINTERS pointers."; 216 217 // Rejects motion events with invalid pointer ids. 218 pointerProperties[0].id = -1; 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*/ 1, pointerProperties, pointerCoords); 223 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 224 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 225 << "Should reject motion events with pointer ids less than 0."; 226 227 pointerProperties[0].id = MAX_POINTER_ID + 1; 228 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 229 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 230 ARBITRARY_TIME, ARBITRARY_TIME, 231 /*pointerCount*/ 1, pointerProperties, pointerCoords); 232 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 233 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 234 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID."; 235 236 // Rejects motion events with duplicate pointer ids. 237 pointerProperties[0].id = 1; 238 pointerProperties[1].id = 1; 239 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 240 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, 241 ARBITRARY_TIME, ARBITRARY_TIME, 242 /*pointerCount*/ 2, pointerProperties, pointerCoords); 243 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 244 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) 245 << "Should reject motion events with duplicate pointer ids."; 246} 247 248} // namespace android 249