Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7be99a70 authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 6d0fec2d: Refactor input reader to support new device types more easily.

Merge commit '6d0fec2de3601821f4f44eeb7d7deedebb2b7117' into gingerbread-plus-aosp

* commit '6d0fec2de3601821f4f44eeb7d7deedebb2b7117':
  Refactor input reader to support new device types more easily.
parents 0a419c71 e57e8950
Loading
Loading
Loading
Loading
+47 −29
Original line number Diff line number Diff line
@@ -59,6 +59,31 @@ namespace android {

class KeyLayoutMap;

/*
 * A raw event as retrieved from the EventHub.
 */
struct RawEvent {
    nsecs_t when;
    int32_t deviceId;
    int32_t type;
    int32_t scanCode;
    int32_t keyCode;
    int32_t value;
    uint32_t flags;
};

/* Describes an absolute axis. */
struct RawAbsoluteAxisInfo {
    bool valid; // true if the information is valid, false otherwise

    int32_t minValue;  // minimum value
    int32_t maxValue;  // maximum value
    int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
    int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise

    inline int32_t getRange() { return maxValue - minValue; }
};

/*
 * Input device classes.
 */
@@ -82,7 +107,10 @@ enum {
    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,

    /* The input device is a gamepad (implies keyboard). */
    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040
    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,

    /* The input device has switches. */
    INPUT_DEVICE_CLASS_SWITCH        = 0x00000080,
};

/*
@@ -114,8 +142,8 @@ public:

    virtual String8 getDeviceName(int32_t deviceId) const = 0;

    virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
            int* outMaxValue, int* outFlat, int* outFuzz) const = 0;
    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
            RawAbsoluteAxisInfo* outAxisInfo) const = 0;

    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
            int32_t* outKeycode, uint32_t* outFlags) const = 0;
@@ -131,26 +159,19 @@ public:
     * If the device needs to remain awake longer than that, then the caller is responsible
     * for taking care of it (say, by poking the power manager user activity timer).
     */
    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
            int32_t* outValue, nsecs_t* outWhen) = 0;
    virtual bool getEvent(RawEvent* outEvent) = 0;

    /*
     * Query current input state.
     *   deviceId may be -1 to search for the device automatically, filtered by class.
     *   deviceClasses may be -1 to ignore device class while searching.
     */
    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t scanCode) const = 0;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t keyCode) const = 0;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
            int32_t sw) const = 0;
    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;

    /*
     * Examine key input devices for specific framework keycode support
     */
    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes,
    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
            uint8_t* outFlags) const = 0;
};

@@ -165,33 +186,28 @@ public:
    
    virtual String8 getDeviceName(int32_t deviceId) const;
    
    virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
            int* outMaxValue, int* outFlat, int* outFuzz) const;
    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
            RawAbsoluteAxisInfo* outAxisInfo) const;

    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
            int32_t* outKeycode, uint32_t* outFlags) const;

    virtual void addExcludedDevice(const char* deviceName);

    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t scanCode) const;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t keyCode) const;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
            int32_t sw) const;
    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;

    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
            const int32_t* keyCodes, uint8_t* outFlags) const;

    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
            int32_t* outValue, nsecs_t* outWhen);
    virtual bool getEvent(RawEvent* outEvent);

protected:
    virtual ~EventHub();
    
private:
    bool openPlatformInput(void);
    int32_t convertDeviceKey_TI_P2(int code);

    int open_device(const char *device);
    int close_device(const char *device);
@@ -220,6 +236,8 @@ private:
    int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
    int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
    int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
    bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
            const int32_t* keyCodes, uint8_t* outFlags) const;

    // Protect all internal state.
    mutable Mutex   mLock;
+72 −11
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@

#include <android/input.h>
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
#include <utils/String8.h>

/*
 * Additional private constants not defined in ndk/ui/input.h.
@@ -47,21 +50,16 @@ struct AInputEvent {
    virtual ~AInputEvent() { }
};

namespace android {

/*
 * A raw event as retrieved from the EventHub.
 * Declare a concrete type for the NDK's input device forward declaration.
 */
struct RawEvent {
    nsecs_t when;
    int32_t deviceId;
    int32_t type;
    int32_t scanCode;
    int32_t keyCode;
    int32_t value;
    uint32_t flags;
struct AInputDevice {
    virtual ~AInputDevice() { }
};


namespace android {

/*
 * Flags that flow alongside events in the input dispatch system to help with certain
 * policy decisions such as waking from device sleep.
@@ -424,6 +422,69 @@ private:
    MotionEvent mMotionEvent;
};

/*
 * Describes the characteristics and capabilities of an input device.
 */
class InputDeviceInfo {
public:
    InputDeviceInfo();
    InputDeviceInfo(const InputDeviceInfo& other);
    ~InputDeviceInfo();

    struct MotionRange {
        float min;
        float max;
        float flat;
        float fuzz;
    };

    void initialize(int32_t id, const String8& name);

    inline int32_t getId() const { return mId; }
    inline const String8 getName() const { return mName; }
    inline uint32_t getSources() const { return mSources; }

    const MotionRange* getMotionRange(int32_t rangeType) const;

    void addSource(uint32_t source);
    void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
    void addMotionRange(int32_t rangeType, const MotionRange& range);

    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
    inline int32_t getKeyboardType() const { return mKeyboardType; }

private:
    int32_t mId;
    String8 mName;
    uint32_t mSources;
    int32_t mKeyboardType;

    KeyedVector<int32_t, MotionRange> mMotionRanges;
};

/*
 * Provides remote access to information about an input device.
 *
 * Note: This is essentially a wrapper for Binder calls into the Window Manager Service.
 */
class InputDeviceProxy : public RefBase, public AInputDevice {
protected:
    InputDeviceProxy();
    virtual ~InputDeviceProxy();

public:
    static void getDeviceIds(Vector<int32_t>& outIds);

    static sp<InputDeviceProxy> getDevice(int32_t id);

    inline const InputDeviceInfo* getInfo() { return & mInfo; }

    // TODO add hasKeys, keymap, etc...

private:
    InputDeviceInfo mInfo;
};


} // namespace android

include/ui/InputDevice.h

deleted100644 → 0
+0 −353
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _UI_INPUT_DEVICE_H
#define _UI_INPUT_DEVICE_H

#include <ui/EventHub.h>
#include <ui/Input.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/BitSet.h>

#include <stddef.h>
#include <unistd.h>

/* Maximum pointer id value supported.
 * (This is limited by our use of BitSet32 to track pointer assignments.) */
#define MAX_POINTER_ID 31

/* Maximum number of historical samples to average. */
#define AVERAGING_HISTORY_SIZE 5


namespace android {

extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation);


/*
 * An input device structure tracks the state of a single input device.
 *
 * This structure is only used by ReaderThread and is not intended to be shared with
 * DispatcherThread (because that would require locking).  This works out fine because
 * DispatcherThread is only interested in cooked event data anyways and does not need
 * any of the low-level data from InputDevice.
 */
struct InputDevice {
    struct AbsoluteAxisInfo {
        bool valid;        // set to true if axis parameters are known, false otherwise

        int32_t minValue;  // minimum value
        int32_t maxValue;  // maximum value
        int32_t range;     // range of values, equal to maxValue - minValue
        int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
        int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
    };

    struct VirtualKey {
        int32_t keyCode;
        int32_t scanCode;
        uint32_t flags;

        // computed hit box, specified in touch screen coords based on known display size
        int32_t hitLeft;
        int32_t hitTop;
        int32_t hitRight;
        int32_t hitBottom;

        inline bool isHit(int32_t x, int32_t y) const {
            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
        }
    };

    struct KeyboardState {
        struct Current {
            int32_t metaState;
            nsecs_t downTime; // time of most recent key down
        } current;

        void reset();
    };

    struct TrackballState {
        struct Accumulator {
            enum {
                FIELD_BTN_MOUSE = 1,
                FIELD_REL_X = 2,
                FIELD_REL_Y = 4
            };

            uint32_t fields;

            bool btnMouse;
            int32_t relX;
            int32_t relY;

            inline void clear() {
                fields = 0;
            }

            inline bool isDirty() {
                return fields != 0;
            }
        } accumulator;

        struct Current {
            bool down;
            nsecs_t downTime;
        } current;

        struct Precalculated {
            float xScale;
            float yScale;
            float xPrecision;
            float yPrecision;
        } precalculated;

        void reset();
    };

    struct SingleTouchScreenState {
        struct Accumulator {
            enum {
                FIELD_BTN_TOUCH = 1,
                FIELD_ABS_X = 2,
                FIELD_ABS_Y = 4,
                FIELD_ABS_PRESSURE = 8,
                FIELD_ABS_TOOL_WIDTH = 16
            };

            uint32_t fields;

            bool btnTouch;
            int32_t absX;
            int32_t absY;
            int32_t absPressure;
            int32_t absToolWidth;

            inline void clear() {
                fields = 0;
            }

            inline bool isDirty() {
                return fields != 0;
            }
        } accumulator;

        struct Current {
            bool down;
            int32_t x;
            int32_t y;
            int32_t pressure;
            int32_t size;
        } current;

        void reset();
    };

    struct MultiTouchScreenState {
        struct Accumulator {
            enum {
                FIELD_ABS_MT_POSITION_X = 1,
                FIELD_ABS_MT_POSITION_Y = 2,
                FIELD_ABS_MT_TOUCH_MAJOR = 4,
                FIELD_ABS_MT_TOUCH_MINOR = 8,
                FIELD_ABS_MT_WIDTH_MAJOR = 16,
                FIELD_ABS_MT_WIDTH_MINOR = 32,
                FIELD_ABS_MT_ORIENTATION = 64,
                FIELD_ABS_MT_TRACKING_ID = 128
            };

            uint32_t pointerCount;
            struct Pointer {
                uint32_t fields;

                int32_t absMTPositionX;
                int32_t absMTPositionY;
                int32_t absMTTouchMajor;
                int32_t absMTTouchMinor;
                int32_t absMTWidthMajor;
                int32_t absMTWidthMinor;
                int32_t absMTOrientation;
                int32_t absMTTrackingId;

                inline void clear() {
                    fields = 0;
                }
            } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks

            inline void clear() {
                pointerCount = 0;
                pointers[0].clear();
            }

            inline bool isDirty() {
                return pointerCount != 0;
            }
        } accumulator;

        void reset();
    };

    struct PointerData {
        uint32_t id;
        int32_t x;
        int32_t y;
        int32_t pressure;
        int32_t size;
        int32_t touchMajor;
        int32_t touchMinor;
        int32_t toolMajor;
        int32_t toolMinor;
        int32_t orientation;
    };

    struct TouchData {
        uint32_t pointerCount;
        PointerData pointers[MAX_POINTERS];
        BitSet32 idBits;
        uint32_t idToIndex[MAX_POINTER_ID + 1];

        void copyFrom(const TouchData& other);

        inline void clear() {
            pointerCount = 0;
            idBits.clear();
        }
    };

    // common state used for both single-touch and multi-touch screens after the initial
    // touch decoding has been performed
    struct TouchScreenState {
        Vector<VirtualKey> virtualKeys;

        struct Parameters {
            bool useBadTouchFilter;
            bool useJumpyTouchFilter;
            bool useAveragingTouchFilter;

            AbsoluteAxisInfo xAxis;
            AbsoluteAxisInfo yAxis;
            AbsoluteAxisInfo pressureAxis;
            AbsoluteAxisInfo sizeAxis;
            AbsoluteAxisInfo orientationAxis;
        } parameters;

        // The touch data of the current sample being processed.
        TouchData currentTouch;

        // The touch data of the previous sample that was processed.  This is updated
        // incrementally while the current sample is being processed.
        TouchData lastTouch;

        // The time the primary pointer last went down.
        nsecs_t downTime;

        struct CurrentVirtualKeyState {
            enum Status {
                STATUS_UP,
                STATUS_DOWN,
                STATUS_CANCELED
            };

            Status status;
            nsecs_t downTime;
            int32_t keyCode;
            int32_t scanCode;
        } currentVirtualKey;

        struct AveragingTouchFilterState {
            // Individual history tracks are stored by pointer id
            uint32_t historyStart[MAX_POINTERS];
            uint32_t historyEnd[MAX_POINTERS];
            struct {
                struct {
                    int32_t x;
                    int32_t y;
                    int32_t pressure;
                } pointers[MAX_POINTERS];
            } historyData[AVERAGING_HISTORY_SIZE];
        } averagingTouchFilter;

        struct JumpTouchFilterState {
            int32_t jumpyPointsDropped;
        } jumpyTouchFilter;

        struct Precalculated {
            int32_t xOrigin;
            float xScale;

            int32_t yOrigin;
            float yScale;

            int32_t pressureOrigin;
            float pressureScale;

            int32_t sizeOrigin;
            float sizeScale;

            float orientationScale;
        } precalculated;

        void reset();

        bool applyBadTouchFilter();
        bool applyJumpyTouchFilter();
        void applyAveragingTouchFilter();
        void calculatePointerIds();

        bool isPointInsideDisplay(int32_t x, int32_t y) const;
        const InputDevice::VirtualKey* findVirtualKeyHit() const;
    };

    InputDevice(int32_t id, uint32_t classes, String8 name);

    int32_t id;
    uint32_t classes;
    String8 name;
    bool ignored;

    KeyboardState keyboard;
    TrackballState trackball;
    TouchScreenState touchScreen;
    union {
        SingleTouchScreenState singleTouchScreen;
        MultiTouchScreenState multiTouchScreen;
    };

    void reset();

    inline bool isKeyboard() const { return classes & INPUT_DEVICE_CLASS_KEYBOARD; }
    inline bool isAlphaKey() const { return classes & INPUT_DEVICE_CLASS_ALPHAKEY; }
    inline bool isTrackball() const { return classes & INPUT_DEVICE_CLASS_TRACKBALL; }
    inline bool isDPad() const { return classes & INPUT_DEVICE_CLASS_DPAD; }
    inline bool isSingleTouchScreen() const { return (classes
            & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT))
            == INPUT_DEVICE_CLASS_TOUCHSCREEN; }
    inline bool isMultiTouchScreen() const { return classes
            & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT; }
    inline bool isTouchScreen() const { return classes
            & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT); }
};

} // namespace android

#endif // _UI_INPUT_DEVICE_H
+29 −20
Original line number Diff line number Diff line
@@ -96,22 +96,28 @@ public:
    virtual void preemptInputDispatch() = 0;

    /* Gets input device configuration. */
    virtual void getInputConfiguration(InputConfiguration* outConfiguration) const = 0;
    virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;

    /*
     * Queries current input state.
     *   deviceId may be -1 to search for the device automatically, filtered by class.
     *   deviceClasses may be -1 to ignore device class while searching.
    /* Gets information about the specified input device.
     * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
     * was no such device.
     */
    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t scanCode) const = 0;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t keyCode) const = 0;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
            int32_t sw) const = 0;
    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;

    /* Gets the list of all registered device ids. */
    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;

    /* Queries current input state. */
    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t scanCode) = 0;
    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t keyCode) = 0;
    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
            int32_t sw) = 0;

    /* Determines whether physical keys exist for the given framework-domain key codes. */
    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0;
    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
};

class InputManager : public InputManagerInterface {
@@ -140,14 +146,17 @@ public:

    virtual void preemptInputDispatch();

    virtual void getInputConfiguration(InputConfiguration* outConfiguration) const;
    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t scanCode) const;
    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
            int32_t keyCode) const;
    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
            int32_t sw) const;
    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t scanCode);
    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t keyCode);
    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
            int32_t sw);
    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);

private:
    sp<InputReaderInterface> mReader;
+622 −131

File changed.

Preview size limit exceeded, changes collapsed.

Loading