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