Home | History | Annotate | Download | only in tests
      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 
     22 namespace android {
     23 
     24 // An arbitrary time value.
     25 static const nsecs_t ARBITRARY_TIME = 1234;
     26 
     27 // An arbitrary device id.
     28 static const int32_t DEVICE_ID = 1;
     29 
     30 // An arbitrary injector pid / uid pair that has permission to inject events.
     31 static const int32_t INJECTOR_PID = 999;
     32 static const int32_t INJECTOR_UID = 1001;
     33 
     34 
     35 // --- FakeInputDispatcherPolicy ---
     36 
     37 class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
     38     InputDispatcherConfiguration mConfig;
     39 
     40 protected:
     41     virtual ~FakeInputDispatcherPolicy() {
     42     }
     43 
     44 public:
     45     FakeInputDispatcherPolicy() {
     46     }
     47 
     48 private:
     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 bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
     69         return true;
     70     }
     71 
     72     virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
     73     }
     74 
     75     virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
     76     }
     77 
     78     virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
     79             const KeyEvent* keyEvent, uint32_t policyFlags) {
     80         return 0;
     81     }
     82 
     83     virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
     84             const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
     85         return false;
     86     }
     87 
     88     virtual void notifySwitch(nsecs_t when,
     89             uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) {
     90     }
     91 
     92     virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
     93     }
     94 
     95     virtual bool checkInjectEventsPermissionNonReentrant(
     96             int32_t injectorPid, int32_t injectorUid) {
     97         return false;
     98     }
     99 };
    100 
    101 
    102 // --- InputDispatcherTest ---
    103 
    104 class InputDispatcherTest : public testing::Test {
    105 protected:
    106     sp<FakeInputDispatcherPolicy> mFakePolicy;
    107     sp<InputDispatcher> mDispatcher;
    108 
    109     virtual void SetUp() {
    110         mFakePolicy = new FakeInputDispatcherPolicy();
    111         mDispatcher = new InputDispatcher(mFakePolicy);
    112     }
    113 
    114     virtual void TearDown() {
    115         mFakePolicy.clear();
    116         mDispatcher.clear();
    117     }
    118 };
    119 
    120 
    121 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
    122     KeyEvent event;
    123 
    124     // Rejects undefined key actions.
    125     event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
    126             /*action*/ -1, 0,
    127             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
    128     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    129             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    130             << "Should reject key events with undefined action.";
    131 
    132     // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
    133     event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
    134             AKEY_EVENT_ACTION_MULTIPLE, 0,
    135             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
    136     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    137             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    138             << "Should reject key events with ACTION_MULTIPLE.";
    139 }
    140 
    141 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
    142     MotionEvent event;
    143     PointerProperties pointerProperties[MAX_POINTERS + 1];
    144     PointerCoords pointerCoords[MAX_POINTERS + 1];
    145     for (int i = 0; i <= MAX_POINTERS; i++) {
    146         pointerProperties[i].clear();
    147         pointerProperties[i].id = i;
    148         pointerCoords[i].clear();
    149     }
    150 
    151     // Rejects undefined motion actions.
    152     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    153             /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    154             ARBITRARY_TIME, ARBITRARY_TIME,
    155             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    156     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    157             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    158             << "Should reject motion events with undefined action.";
    159 
    160     // Rejects pointer down with invalid index.
    161     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    162             AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
    163             0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    164             ARBITRARY_TIME, ARBITRARY_TIME,
    165             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    166     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    167             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    168             << "Should reject motion events with pointer down index too large.";
    169 
    170     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    171             AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
    172             0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    173             ARBITRARY_TIME, ARBITRARY_TIME,
    174             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    175     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    176             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    177             << "Should reject motion events with pointer down index too small.";
    178 
    179     // Rejects pointer up with invalid index.
    180     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    181             AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
    182             0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    183             ARBITRARY_TIME, ARBITRARY_TIME,
    184             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    185     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    186             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    187             << "Should reject motion events with pointer up index too large.";
    188 
    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(&event,
    195             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    196             << "Should reject motion events with pointer up index too small.";
    197 
    198     // Rejects motion events with invalid number of pointers.
    199     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    200             AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    201             ARBITRARY_TIME, ARBITRARY_TIME,
    202             /*pointerCount*/ 0, pointerProperties, pointerCoords);
    203     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    204             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    205             << "Should reject motion events with 0 pointers.";
    206 
    207     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    208             AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    209             ARBITRARY_TIME, ARBITRARY_TIME,
    210             /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
    211     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    212             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    213             << "Should reject motion events with more than MAX_POINTERS pointers.";
    214 
    215     // Rejects motion events with invalid pointer ids.
    216     pointerProperties[0].id = -1;
    217     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    218             AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    219             ARBITRARY_TIME, ARBITRARY_TIME,
    220             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    221     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    222             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    223             << "Should reject motion events with pointer ids less than 0.";
    224 
    225     pointerProperties[0].id = MAX_POINTER_ID + 1;
    226     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    227             AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    228             ARBITRARY_TIME, ARBITRARY_TIME,
    229             /*pointerCount*/ 1, pointerProperties, pointerCoords);
    230     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    231             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    232             << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
    233 
    234     // Rejects motion events with duplicate pointer ids.
    235     pointerProperties[0].id = 1;
    236     pointerProperties[1].id = 1;
    237     event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
    238             AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
    239             ARBITRARY_TIME, ARBITRARY_TIME,
    240             /*pointerCount*/ 2, pointerProperties, pointerCoords);
    241     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
    242             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
    243             << "Should reject motion events with duplicate pointer ids.";
    244 }
    245 
    246 } // namespace android
    247