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