InputDispatcher_test.cpp revision f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8
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 display id. 31static const int32_t DISPLAY_ID = 0; 32 33// 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); 132 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 133 &event, DISPLAY_ID, 134 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); 141 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 142 &event, DISPLAY_ID, 143 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); 162 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 163 &event, DISPLAY_ID, 164 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); 173 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 174 &event, DISPLAY_ID, 175 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); 183 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 184 &event, DISPLAY_ID, 185 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); 194 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 195 &event, DISPLAY_ID, 196 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); 204 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 205 &event, DISPLAY_ID, 206 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); 214 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 215 &event, DISPLAY_ID, 216 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); 223 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 224 &event, DISPLAY_ID, 225 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); 234 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 235 &event, DISPLAY_ID, 236 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); 244 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 245 &event, DISPLAY_ID, 246 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); 256 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( 257 &event, DISPLAY_ID, 258 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 263