Home | History | Annotate | Download | only in tests
      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