1 // 2 // Copyright 2010 The Android Open Source Project 3 // 4 5 #include <ui/InputDispatcher.h> 6 #include <gtest/gtest.h> 7 #include <linux/input.h> 8 9 namespace android { 10 11 // An arbitrary time value. 12 static const nsecs_t ARBITRARY_TIME = 1234; 13 14 // An arbitrary device id. 15 static const int32_t DEVICE_ID = 1; 16 17 // An arbitrary injector pid / uid pair that has permission to inject events. 18 static const int32_t INJECTOR_PID = 999; 19 static const int32_t INJECTOR_UID = 1001; 20 21 22 // --- FakeInputDispatcherPolicy --- 23 24 class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface { 25 protected: 26 virtual ~FakeInputDispatcherPolicy() { 27 } 28 29 public: 30 FakeInputDispatcherPolicy() { 31 } 32 33 private: 34 virtual void notifyConfigurationChanged(nsecs_t when) { 35 } 36 37 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, 38 const sp<InputChannel>& inputChannel) { 39 return 0; 40 } 41 42 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) { 43 } 44 45 virtual nsecs_t getKeyRepeatTimeout() { 46 return 500 * 1000000LL; 47 } 48 49 virtual nsecs_t getKeyRepeatDelay() { 50 return 50 * 1000000LL; 51 } 52 53 virtual int32_t getMaxEventsPerSecond() { 54 return 60; 55 } 56 57 virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId, 58 int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode, 59 uint32_t& policyFlags) { 60 } 61 62 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) { 63 } 64 65 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel, 66 const KeyEvent* keyEvent, uint32_t policyFlags) { 67 return false; 68 } 69 70 virtual void notifySwitch(nsecs_t when, 71 int32_t switchCode, int32_t switchValue, uint32_t policyFlags) { 72 } 73 74 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) { 75 } 76 77 virtual bool checkInjectEventsPermissionNonReentrant( 78 int32_t injectorPid, int32_t injectorUid) { 79 return false; 80 } 81 }; 82 83 84 // --- InputDispatcherTest --- 85 86 class InputDispatcherTest : public testing::Test { 87 protected: 88 sp<FakeInputDispatcherPolicy> mFakePolicy; 89 sp<InputDispatcher> mDispatcher; 90 91 virtual void SetUp() { 92 mFakePolicy = new FakeInputDispatcherPolicy(); 93 mDispatcher = new InputDispatcher(mFakePolicy); 94 } 95 96 virtual void TearDown() { 97 mFakePolicy.clear(); 98 mDispatcher.clear(); 99 } 100 }; 101 102 103 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { 104 KeyEvent event; 105 106 // Rejects undefined key actions. 107 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, 108 /*action*/ -1, 0, 109 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); 110 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 111 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 112 << "Should reject key events with undefined action."; 113 114 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API. 115 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, 116 AKEY_EVENT_ACTION_MULTIPLE, 0, 117 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); 118 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 119 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 120 << "Should reject key events with ACTION_MULTIPLE."; 121 } 122 123 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 124 MotionEvent event; 125 int32_t pointerIds[MAX_POINTERS + 1]; 126 PointerCoords pointerCoords[MAX_POINTERS + 1]; 127 for (int i = 0; i <= MAX_POINTERS; i++) { 128 pointerIds[i] = i; 129 } 130 131 // Rejects undefined motion actions. 132 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 133 /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 134 ARBITRARY_TIME, ARBITRARY_TIME, 135 /*pointerCount*/ 1, pointerIds, pointerCoords); 136 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 137 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 138 << "Should reject motion events with undefined action."; 139 140 // Rejects pointer down with invalid index. 141 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 142 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 143 0, 0, AMETA_NONE, 0, 0, 0, 0, 144 ARBITRARY_TIME, ARBITRARY_TIME, 145 /*pointerCount*/ 1, pointerIds, pointerCoords); 146 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 147 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 148 << "Should reject motion events with pointer down index too large."; 149 150 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 151 AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 152 0, 0, AMETA_NONE, 0, 0, 0, 0, 153 ARBITRARY_TIME, ARBITRARY_TIME, 154 /*pointerCount*/ 1, pointerIds, pointerCoords); 155 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 156 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 157 << "Should reject motion events with pointer down index too small."; 158 159 // Rejects pointer up with invalid index. 160 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 161 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 162 0, 0, AMETA_NONE, 0, 0, 0, 0, 163 ARBITRARY_TIME, ARBITRARY_TIME, 164 /*pointerCount*/ 1, pointerIds, pointerCoords); 165 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 166 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 167 << "Should reject motion events with pointer up index too large."; 168 169 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 170 AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 171 0, 0, AMETA_NONE, 0, 0, 0, 0, 172 ARBITRARY_TIME, ARBITRARY_TIME, 173 /*pointerCount*/ 1, pointerIds, pointerCoords); 174 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 175 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 176 << "Should reject motion events with pointer up index too small."; 177 178 // Rejects motion events with invalid number of pointers. 179 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 180 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 181 ARBITRARY_TIME, ARBITRARY_TIME, 182 /*pointerCount*/ 0, pointerIds, pointerCoords); 183 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 184 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 185 << "Should reject motion events with 0 pointers."; 186 187 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 188 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 189 ARBITRARY_TIME, ARBITRARY_TIME, 190 /*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords); 191 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 192 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 193 << "Should reject motion events with more than MAX_POINTERS pointers."; 194 195 // Rejects motion events with invalid pointer ids. 196 pointerIds[0] = -1; 197 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 198 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 199 ARBITRARY_TIME, ARBITRARY_TIME, 200 /*pointerCount*/ 1, pointerIds, pointerCoords); 201 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 202 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 203 << "Should reject motion events with pointer ids less than 0."; 204 205 pointerIds[0] = MAX_POINTER_ID + 1; 206 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 207 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 208 ARBITRARY_TIME, ARBITRARY_TIME, 209 /*pointerCount*/ 1, pointerIds, pointerCoords); 210 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 211 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 212 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID."; 213 214 // Rejects motion events with duplicate pointer ids. 215 pointerIds[0] = 1; 216 pointerIds[1] = 1; 217 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, 218 AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 219 ARBITRARY_TIME, ARBITRARY_TIME, 220 /*pointerCount*/ 2, pointerIds, pointerCoords); 221 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, 222 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0)) 223 << "Should reject motion events with duplicate pointer ids."; 224 } 225 226 } // namespace android 227