Home | History | Annotate | Download | only in input
      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 #ifndef _LIBINPUT_INPUT_H
     18 #define _LIBINPUT_INPUT_H
     19 
     20 /**
     21  * Native input event structures.
     22  */
     23 
     24 #include <android/input.h>
     25 #include <utils/BitSet.h>
     26 #include <utils/KeyedVector.h>
     27 #include <utils/RefBase.h>
     28 #include <utils/String8.h>
     29 #include <utils/Timers.h>
     30 #include <utils/Vector.h>
     31 #include <stdint.h>
     32 
     33 /*
     34  * Additional private constants not defined in ndk/ui/input.h.
     35  */
     36 enum {
     37     /* Signifies that the key is being predispatched */
     38     AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,
     39 
     40     /* Private control to determine when an app is tracking a key sequence. */
     41     AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,
     42 
     43     /* Key event is inconsistent with previously sent key events. */
     44     AKEY_EVENT_FLAG_TAINTED = 0x80000000,
     45 };
     46 
     47 enum {
     48 
     49     /**
     50      * This flag indicates that the window that received this motion event is partly
     51      * or wholly obscured by another visible window above it.  This flag is set to true
     52      * even if the event did not directly pass through the obscured area.
     53      * A security sensitive application can check this flag to identify situations in which
     54      * a malicious application may have covered up part of its content for the purpose
     55      * of misleading the user or hijacking touches.  An appropriate response might be
     56      * to drop the suspect touches or to take additional precautions to confirm the user's
     57      * actual intent.
     58      */
     59     AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2,
     60 
     61     /* Motion event is inconsistent with previously sent motion events. */
     62     AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
     63 };
     64 
     65 enum {
     66     /* Used when a motion event is not associated with any display.
     67      * Typically used for non-pointer events. */
     68     ADISPLAY_ID_NONE = -1,
     69 
     70     /* The default display id. */
     71     ADISPLAY_ID_DEFAULT = 0,
     72 };
     73 
     74 enum {
     75     /*
     76      * Indicates that an input device has switches.
     77      * This input source flag is hidden from the API because switches are only used by the system
     78      * and applications have no way to interact with them.
     79      */
     80     AINPUT_SOURCE_SWITCH = 0x80000000,
     81 };
     82 
     83 enum {
     84     /**
     85      * Constants for LEDs. Hidden from the API since we don't actually expose a way to interact
     86      * with LEDs to developers
     87      *
     88      * NOTE: If you add LEDs here, you must also add them to InputEventLabels.h
     89      */
     90 
     91     ALED_NUM_LOCK = 0x00,
     92     ALED_CAPS_LOCK = 0x01,
     93     ALED_SCROLL_LOCK = 0x02,
     94     ALED_COMPOSE = 0x03,
     95     ALED_KANA = 0x04,
     96     ALED_SLEEP = 0x05,
     97     ALED_SUSPEND = 0x06,
     98     ALED_MUTE = 0x07,
     99     ALED_MISC = 0x08,
    100     ALED_MAIL = 0x09,
    101     ALED_CHARGING = 0x0a,
    102     ALED_CONTROLLER_1 = 0x10,
    103     ALED_CONTROLLER_2 = 0x11,
    104     ALED_CONTROLLER_3 = 0x12,
    105     ALED_CONTROLLER_4 = 0x13,
    106 };
    107 
    108 /* Maximum number of controller LEDs we support */
    109 #define MAX_CONTROLLER_LEDS 4
    110 
    111 /*
    112  * SystemUiVisibility constants from View.
    113  */
    114 enum {
    115     ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
    116     ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
    117 };
    118 
    119 /*
    120  * Maximum number of pointers supported per motion event.
    121  * Smallest number of pointers is 1.
    122  * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
    123  * will occasionally emit 11.  There is not much harm making this constant bigger.)
    124  */
    125 #define MAX_POINTERS 16
    126 
    127 /*
    128  * Maximum number of samples supported per motion event.
    129  */
    130 #define MAX_SAMPLES UINT16_MAX
    131 
    132 /*
    133  * Maximum pointer id value supported in a motion event.
    134  * Smallest pointer id is 0.
    135  * (This is limited by our use of BitSet32 to track pointer assignments.)
    136  */
    137 #define MAX_POINTER_ID 31
    138 
    139 /*
    140  * Declare a concrete type for the NDK's input event forward declaration.
    141  */
    142 struct AInputEvent {
    143     virtual ~AInputEvent() { }
    144 };
    145 
    146 /*
    147  * Declare a concrete type for the NDK's input device forward declaration.
    148  */
    149 struct AInputDevice {
    150     virtual ~AInputDevice() { }
    151 };
    152 
    153 
    154 namespace android {
    155 
    156 #ifdef __ANDROID__
    157 class Parcel;
    158 #endif
    159 
    160 /*
    161  * Flags that flow alongside events in the input dispatch system to help with certain
    162  * policy decisions such as waking from device sleep.
    163  *
    164  * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
    165  */
    166 enum {
    167     /* These flags originate in RawEvents and are generally set in the key map.
    168      * NOTE: If you want a flag to be able to set in a keylayout file, then you must add it to
    169      * InputEventLabels.h as well. */
    170 
    171     // Indicates that the event should wake the device.
    172     POLICY_FLAG_WAKE = 0x00000001,
    173 
    174     // Indicates that the key is virtual, such as a capacitive button, and should
    175     // generate haptic feedback.  Virtual keys may be suppressed for some time
    176     // after a recent touch to prevent accidental activation of virtual keys adjacent
    177     // to the touch screen during an edge swipe.
    178     POLICY_FLAG_VIRTUAL = 0x00000002,
    179 
    180     // Indicates that the key is the special function modifier.
    181     POLICY_FLAG_FUNCTION = 0x00000004,
    182 
    183     // Indicates that the key represents a special gesture that has been detected by
    184     // the touch firmware or driver.  Causes touch events from the same device to be canceled.
    185     POLICY_FLAG_GESTURE = 0x00000008,
    186 
    187     POLICY_FLAG_RAW_MASK = 0x0000ffff,
    188 
    189     /* These flags are set by the input dispatcher. */
    190 
    191     // Indicates that the input event was injected.
    192     POLICY_FLAG_INJECTED = 0x01000000,
    193 
    194     // Indicates that the input event is from a trusted source such as a directly attached
    195     // input device or an application with system-wide event injection permission.
    196     POLICY_FLAG_TRUSTED = 0x02000000,
    197 
    198     // Indicates that the input event has passed through an input filter.
    199     POLICY_FLAG_FILTERED = 0x04000000,
    200 
    201     // Disables automatic key repeating behavior.
    202     POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,
    203 
    204     /* These flags are set by the input reader policy as it intercepts each event. */
    205 
    206     // Indicates that the device was in an interactive state when the
    207     // event was intercepted.
    208     POLICY_FLAG_INTERACTIVE = 0x20000000,
    209 
    210     // Indicates that the event should be dispatched to applications.
    211     // The input event should still be sent to the InputDispatcher so that it can see all
    212     // input events received include those that it will not deliver.
    213     POLICY_FLAG_PASS_TO_USER = 0x40000000,
    214 };
    215 
    216 /*
    217  * Pointer coordinate data.
    218  */
    219 struct PointerCoords {
    220     enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128
    221 
    222     // Bitfield of axes that are present in this structure.
    223     uint64_t bits __attribute__((aligned(8)));
    224 
    225     // Values of axes that are stored in this structure packed in order by axis id
    226     // for each axis that is present in the structure according to 'bits'.
    227     float values[MAX_AXES];
    228 
    229     inline void clear() {
    230         BitSet64::clear(bits);
    231     }
    232 
    233     bool isEmpty() const {
    234         return BitSet64::isEmpty(bits);
    235     }
    236 
    237     float getAxisValue(int32_t axis) const;
    238     status_t setAxisValue(int32_t axis, float value);
    239 
    240     void scale(float scale);
    241     void applyOffset(float xOffset, float yOffset);
    242 
    243     inline float getX() const {
    244         return getAxisValue(AMOTION_EVENT_AXIS_X);
    245     }
    246 
    247     inline float getY() const {
    248         return getAxisValue(AMOTION_EVENT_AXIS_Y);
    249     }
    250 
    251 #ifdef __ANDROID__
    252     status_t readFromParcel(Parcel* parcel);
    253     status_t writeToParcel(Parcel* parcel) const;
    254 #endif
    255 
    256     bool operator==(const PointerCoords& other) const;
    257     inline bool operator!=(const PointerCoords& other) const {
    258         return !(*this == other);
    259     }
    260 
    261     void copyFrom(const PointerCoords& other);
    262 
    263 private:
    264     void tooManyAxes(int axis);
    265 };
    266 
    267 /*
    268  * Pointer property data.
    269  */
    270 struct PointerProperties {
    271     // The id of the pointer.
    272     int32_t id;
    273 
    274     // The pointer tool type.
    275     int32_t toolType;
    276 
    277     inline void clear() {
    278         id = -1;
    279         toolType = 0;
    280     }
    281 
    282     bool operator==(const PointerProperties& other) const;
    283     inline bool operator!=(const PointerProperties& other) const {
    284         return !(*this == other);
    285     }
    286 
    287     void copyFrom(const PointerProperties& other);
    288 };
    289 
    290 /*
    291  * Input events.
    292  */
    293 class InputEvent : public AInputEvent {
    294 public:
    295     virtual ~InputEvent() { }
    296 
    297     virtual int32_t getType() const = 0;
    298 
    299     inline int32_t getDeviceId() const { return mDeviceId; }
    300 
    301     inline int32_t getSource() const { return mSource; }
    302 
    303     inline void setSource(int32_t source) { mSource = source; }
    304 
    305 protected:
    306     void initialize(int32_t deviceId, int32_t source);
    307     void initialize(const InputEvent& from);
    308 
    309     int32_t mDeviceId;
    310     int32_t mSource;
    311 };
    312 
    313 /*
    314  * Key events.
    315  */
    316 class KeyEvent : public InputEvent {
    317 public:
    318     virtual ~KeyEvent() { }
    319 
    320     virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
    321 
    322     inline int32_t getAction() const { return mAction; }
    323 
    324     inline int32_t getFlags() const { return mFlags; }
    325 
    326     inline void setFlags(int32_t flags) { mFlags = flags; }
    327 
    328     inline int32_t getKeyCode() const { return mKeyCode; }
    329 
    330     inline int32_t getScanCode() const { return mScanCode; }
    331 
    332     inline int32_t getMetaState() const { return mMetaState; }
    333 
    334     inline int32_t getRepeatCount() const { return mRepeatCount; }
    335 
    336     inline nsecs_t getDownTime() const { return mDownTime; }
    337 
    338     inline nsecs_t getEventTime() const { return mEventTime; }
    339 
    340     static const char* getLabel(int32_t keyCode);
    341     static int32_t getKeyCodeFromLabel(const char* label);
    342 
    343     void initialize(
    344             int32_t deviceId,
    345             int32_t source,
    346             int32_t action,
    347             int32_t flags,
    348             int32_t keyCode,
    349             int32_t scanCode,
    350             int32_t metaState,
    351             int32_t repeatCount,
    352             nsecs_t downTime,
    353             nsecs_t eventTime);
    354     void initialize(const KeyEvent& from);
    355 
    356 protected:
    357     int32_t mAction;
    358     int32_t mFlags;
    359     int32_t mKeyCode;
    360     int32_t mScanCode;
    361     int32_t mMetaState;
    362     int32_t mRepeatCount;
    363     nsecs_t mDownTime;
    364     nsecs_t mEventTime;
    365 };
    366 
    367 /*
    368  * Motion events.
    369  */
    370 class MotionEvent : public InputEvent {
    371 public:
    372     virtual ~MotionEvent() { }
    373 
    374     virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
    375 
    376     inline int32_t getAction() const { return mAction; }
    377 
    378     inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
    379 
    380     inline int32_t getActionIndex() const {
    381         return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
    382                 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
    383     }
    384 
    385     inline void setAction(int32_t action) { mAction = action; }
    386 
    387     inline int32_t getFlags() const { return mFlags; }
    388 
    389     inline void setFlags(int32_t flags) { mFlags = flags; }
    390 
    391     inline int32_t getEdgeFlags() const { return mEdgeFlags; }
    392 
    393     inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
    394 
    395     inline int32_t getMetaState() const { return mMetaState; }
    396 
    397     inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
    398 
    399     inline int32_t getButtonState() const { return mButtonState; }
    400 
    401     inline void setButtonState(int32_t buttonState) { mButtonState = buttonState; }
    402 
    403     inline int32_t getActionButton() const { return mActionButton; }
    404 
    405     inline void setActionButton(int32_t button) { mActionButton = button; }
    406 
    407     inline float getXOffset() const { return mXOffset; }
    408 
    409     inline float getYOffset() const { return mYOffset; }
    410 
    411     inline float getXPrecision() const { return mXPrecision; }
    412 
    413     inline float getYPrecision() const { return mYPrecision; }
    414 
    415     inline nsecs_t getDownTime() const { return mDownTime; }
    416 
    417     inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
    418 
    419     inline size_t getPointerCount() const { return mPointerProperties.size(); }
    420 
    421     inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
    422         return &mPointerProperties[pointerIndex];
    423     }
    424 
    425     inline int32_t getPointerId(size_t pointerIndex) const {
    426         return mPointerProperties[pointerIndex].id;
    427     }
    428 
    429     inline int32_t getToolType(size_t pointerIndex) const {
    430         return mPointerProperties[pointerIndex].toolType;
    431     }
    432 
    433     inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
    434 
    435     const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
    436 
    437     float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
    438 
    439     inline float getRawX(size_t pointerIndex) const {
    440         return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
    441     }
    442 
    443     inline float getRawY(size_t pointerIndex) const {
    444         return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
    445     }
    446 
    447     float getAxisValue(int32_t axis, size_t pointerIndex) const;
    448 
    449     inline float getX(size_t pointerIndex) const {
    450         return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
    451     }
    452 
    453     inline float getY(size_t pointerIndex) const {
    454         return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
    455     }
    456 
    457     inline float getPressure(size_t pointerIndex) const {
    458         return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
    459     }
    460 
    461     inline float getSize(size_t pointerIndex) const {
    462         return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
    463     }
    464 
    465     inline float getTouchMajor(size_t pointerIndex) const {
    466         return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
    467     }
    468 
    469     inline float getTouchMinor(size_t pointerIndex) const {
    470         return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
    471     }
    472 
    473     inline float getToolMajor(size_t pointerIndex) const {
    474         return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
    475     }
    476 
    477     inline float getToolMinor(size_t pointerIndex) const {
    478         return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
    479     }
    480 
    481     inline float getOrientation(size_t pointerIndex) const {
    482         return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
    483     }
    484 
    485     inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
    486 
    487     inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
    488         return mSampleEventTimes[historicalIndex];
    489     }
    490 
    491     const PointerCoords* getHistoricalRawPointerCoords(
    492             size_t pointerIndex, size_t historicalIndex) const;
    493 
    494     float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
    495             size_t historicalIndex) const;
    496 
    497     inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
    498         return getHistoricalRawAxisValue(
    499                 AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
    500     }
    501 
    502     inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
    503         return getHistoricalRawAxisValue(
    504                 AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
    505     }
    506 
    507     float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
    508 
    509     inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
    510         return getHistoricalAxisValue(
    511                 AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
    512     }
    513 
    514     inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
    515         return getHistoricalAxisValue(
    516                 AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
    517     }
    518 
    519     inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
    520         return getHistoricalAxisValue(
    521                 AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
    522     }
    523 
    524     inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
    525         return getHistoricalAxisValue(
    526                 AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
    527     }
    528 
    529     inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
    530         return getHistoricalAxisValue(
    531                 AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
    532     }
    533 
    534     inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
    535         return getHistoricalAxisValue(
    536                 AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
    537     }
    538 
    539     inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
    540         return getHistoricalAxisValue(
    541                 AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
    542     }
    543 
    544     inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
    545         return getHistoricalAxisValue(
    546                 AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
    547     }
    548 
    549     inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
    550         return getHistoricalAxisValue(
    551                 AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
    552     }
    553 
    554     ssize_t findPointerIndex(int32_t pointerId) const;
    555 
    556     void initialize(
    557             int32_t deviceId,
    558             int32_t source,
    559             int32_t action,
    560             int32_t actionButton,
    561             int32_t flags,
    562             int32_t edgeFlags,
    563             int32_t metaState,
    564             int32_t buttonState,
    565             float xOffset,
    566             float yOffset,
    567             float xPrecision,
    568             float yPrecision,
    569             nsecs_t downTime,
    570             nsecs_t eventTime,
    571             size_t pointerCount,
    572             const PointerProperties* pointerProperties,
    573             const PointerCoords* pointerCoords);
    574 
    575     void copyFrom(const MotionEvent* other, bool keepHistory);
    576 
    577     void addSample(
    578             nsecs_t eventTime,
    579             const PointerCoords* pointerCoords);
    580 
    581     void offsetLocation(float xOffset, float yOffset);
    582 
    583     void scale(float scaleFactor);
    584 
    585     // Apply 3x3 perspective matrix transformation.
    586     // Matrix is in row-major form and compatible with SkMatrix.
    587     void transform(const float matrix[9]);
    588 
    589 #ifdef __ANDROID__
    590     status_t readFromParcel(Parcel* parcel);
    591     status_t writeToParcel(Parcel* parcel) const;
    592 #endif
    593 
    594     static bool isTouchEvent(int32_t source, int32_t action);
    595     inline bool isTouchEvent() const {
    596         return isTouchEvent(mSource, mAction);
    597     }
    598 
    599     // Low-level accessors.
    600     inline const PointerProperties* getPointerProperties() const {
    601         return mPointerProperties.array();
    602     }
    603     inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
    604     inline const PointerCoords* getSamplePointerCoords() const {
    605             return mSamplePointerCoords.array();
    606     }
    607 
    608     static const char* getLabel(int32_t axis);
    609     static int32_t getAxisFromLabel(const char* label);
    610 
    611 protected:
    612     int32_t mAction;
    613     int32_t mActionButton;
    614     int32_t mFlags;
    615     int32_t mEdgeFlags;
    616     int32_t mMetaState;
    617     int32_t mButtonState;
    618     float mXOffset;
    619     float mYOffset;
    620     float mXPrecision;
    621     float mYPrecision;
    622     nsecs_t mDownTime;
    623     Vector<PointerProperties> mPointerProperties;
    624     Vector<nsecs_t> mSampleEventTimes;
    625     Vector<PointerCoords> mSamplePointerCoords;
    626 };
    627 
    628 /*
    629  * Input event factory.
    630  */
    631 class InputEventFactoryInterface {
    632 protected:
    633     virtual ~InputEventFactoryInterface() { }
    634 
    635 public:
    636     InputEventFactoryInterface() { }
    637 
    638     virtual KeyEvent* createKeyEvent() = 0;
    639     virtual MotionEvent* createMotionEvent() = 0;
    640 };
    641 
    642 /*
    643  * A simple input event factory implementation that uses a single preallocated instance
    644  * of each type of input event that are reused for each request.
    645  */
    646 class PreallocatedInputEventFactory : public InputEventFactoryInterface {
    647 public:
    648     PreallocatedInputEventFactory() { }
    649     virtual ~PreallocatedInputEventFactory() { }
    650 
    651     virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
    652     virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
    653 
    654 private:
    655     KeyEvent mKeyEvent;
    656     MotionEvent mMotionEvent;
    657 };
    658 
    659 /*
    660  * An input event factory implementation that maintains a pool of input events.
    661  */
    662 class PooledInputEventFactory : public InputEventFactoryInterface {
    663 public:
    664     PooledInputEventFactory(size_t maxPoolSize = 20);
    665     virtual ~PooledInputEventFactory();
    666 
    667     virtual KeyEvent* createKeyEvent();
    668     virtual MotionEvent* createMotionEvent();
    669 
    670     void recycle(InputEvent* event);
    671 
    672 private:
    673     const size_t mMaxPoolSize;
    674 
    675     Vector<KeyEvent*> mKeyEventPool;
    676     Vector<MotionEvent*> mMotionEventPool;
    677 };
    678 
    679 } // namespace android
    680 
    681 #endif // _LIBINPUT_INPUT_H
    682