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

Commit 6d0fec2d authored by Jeff Brown's avatar Jeff Brown
Browse files

Refactor input reader to support new device types more easily.

Refactored the input reader so that each raw input protocol is handled
by a separate subclass of the new InputMapper type.  This way, behaviors
pertaining to keyboard, trackballs, touchscreens, switches and other
devices are clearly distinguished for improved maintainability.

Added partial support for describing capabilities of input devices
(incomplete and untested for now, will be fleshed out in later commits).

Simplified EventHub interface somewhat since InputReader is taking over
more of the work.

Cleaned up some of the interactions between InputManager and
WindowManagerService related to reading input state.

Fixed swiping finger from screen edge into display area.

Added logging of device information to 'dumpsys window'.

Change-Id: I17faffc33e3aec3a0f33f0b37e81a70609378612
parent b350bec5
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -173756,6 +173756,17 @@
 visibility="public"
>
</method>
<method name="getKeyboardType"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getMotionRange"
 return="android.view.InputDevice.MotionRange"
 abstract="false"
@@ -173804,6 +173815,39 @@
<parameter name="keyCode" type="int">
</parameter>
</method>
<field name="KEYBOARD_TYPE_ALPHABETIC"
 type="int"
 transient="false"
 volatile="false"
 value="2"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="KEYBOARD_TYPE_NONE"
 type="int"
 transient="false"
 volatile="false"
 value="0"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="KEYBOARD_TYPE_NON_ALPHABETIC"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="MOTION_RANGE_ORIENTATION"
 type="int"
 transient="false"
@@ -173903,6 +173947,17 @@
 visibility="public"
>
</field>
<field name="SOURCE_ANY"
 type="int"
 transient="false"
 volatile="false"
 value="-256"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="SOURCE_CLASS_BUTTON"
 type="int"
 transient="false"
+32 −0
Original line number Diff line number Diff line
@@ -30,11 +30,13 @@ package android.view;
 * As a further wrinkle, different kinds of input sources uses different coordinate systems
 * to describe motion events.  Refer to the comments on the input source constants for
 * the appropriate interpretation.
 * </p>
 */
public final class InputDevice {
    private int mId;
    private String mName;
    private int mSources;
    private int mKeyboardType;
    
    /**
     * A mask for input source classes.
@@ -174,6 +176,12 @@ public final class InputDevice {
     */
    public static final int SOURCE_JOYSTICK_RIGHT = 0x02000000 | SOURCE_CLASS_JOYSTICK;
    
    /**
     * A special input source constant that is used when filtering input devices
     * to match devices that provide any type of input source.
     */
    public static final int SOURCE_ANY = 0xffffff00;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#x}.
     * 
@@ -238,6 +246,22 @@ public final class InputDevice {
     */
    public static final int MOTION_RANGE_ORIENTATION = 8;
    
    /**
     * There is no keyboard.
     */
    public static final int KEYBOARD_TYPE_NONE = 0;
    
    /**
     * The keyboard is not fully alphabetic.  It may be a numeric keypad or an assortment
     * of buttons that are not mapped as alphabetic keys suitable for text input.
     */
    public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1;
    
    /**
     * The keyboard supports a complement of alphabetic keys.
     */
    public static final int KEYBOARD_TYPE_ALPHABETIC = 2;

    /**
     * Gets information about the input device with the specified id.
     * @param id The device id.
@@ -264,6 +288,14 @@ public final class InputDevice {
        return mSources;
    }
    
    /**
     * Gets the keyboard type.
     * @return The keyboard type.
     */
    public int getKeyboardType() {
        return mKeyboardType;
    }
    
    /**
     * Gets the key character map associated with this input device.
     * @return The key character map.
+17 −17
Original line number Diff line number Diff line
@@ -181,61 +181,61 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     * Offset for the sample's X coordinate.
     * @hide
     */
    static public final int SAMPLE_X = 0;
    static private final int SAMPLE_X = 0;
    
    /**
     * Offset for the sample's Y coordinate.
     * @hide
     */
    static public final int SAMPLE_Y = 1;
    static private final int SAMPLE_Y = 1;
    
    /**
     * Offset for the sample's pressure.
     * @hide
     */
    static public final int SAMPLE_PRESSURE = 2;
    static private final int SAMPLE_PRESSURE = 2;
    
    /**
     * Offset for the sample's size
     * @hide
     */
    static public final int SAMPLE_SIZE = 3;
    static private final int SAMPLE_SIZE = 3;
    
    /**
     * Offset for the sample's touch major axis length.
     * @hide
     */
    static public final int SAMPLE_TOUCH_MAJOR = 4;
    static private final int SAMPLE_TOUCH_MAJOR = 4;

    /**
     * Offset for the sample's touch minor axis length.
     * @hide
     */
    static public final int SAMPLE_TOUCH_MINOR = 5;
    static private final int SAMPLE_TOUCH_MINOR = 5;
    
    /**
     * Offset for the sample's tool major axis length.
     * @hide
     */
    static public final int SAMPLE_TOOL_MAJOR = 6;
    static private final int SAMPLE_TOOL_MAJOR = 6;

    /**
     * Offset for the sample's tool minor axis length.
     * @hide
     */
    static public final int SAMPLE_TOOL_MINOR = 7;
    static private final int SAMPLE_TOOL_MINOR = 7;
    
    /**
     * Offset for the sample's orientation.
     * @hide
     */
    static public final int SAMPLE_ORIENTATION = 8;
    static private final int SAMPLE_ORIENTATION = 8;

    /**
     * Number of data items for each sample.
     * @hide
     */
    static public final int NUM_SAMPLE_DATA = 9;
    static private final int NUM_SAMPLE_DATA = 9;
    
    /**
     * Number of possible pointers.
@@ -918,7 +918,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     * upwards, is perfectly circular or is of unknown orientation.  A positive angle
     * indicates that the major axis of contact is oriented to the right.  A negative angle
     * indicates that the major axis of contact is oriented to the left.
     * The full range is from -PI/4 radians (finger pointing fully left) to PI/4 radians
     * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
     * (finger pointing fully right).
     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
     * (the first pointer that is down) to {@link #getPointerCount()}-1.
@@ -1614,28 +1614,28 @@ public final class MotionEvent extends InputEvent implements Parcelable {
         * upwards, is perfectly circular or is of unknown orientation.  A positive angle
         * indicates that the major axis of contact is oriented to the right.  A negative angle
         * indicates that the major axis of contact is oriented to the left.
         * The full range is from -PI/4 radians (finger pointing fully left) to PI/4 radians
         * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
         * (finger pointing fully right).
         */
        public float orientation;
        
        /*
        private static final float PI_8 = (float) (Math.PI / 8);
        private static final float PI_4 = (float) (Math.PI / 4);
        
        public float getTouchWidth() {
            return Math.abs(orientation) > PI_8 ? touchMajor : touchMinor;
            return Math.abs(orientation) > PI_4 ? touchMajor : touchMinor;
        }
        
        public float getTouchHeight() {
            return Math.abs(orientation) > PI_8 ? touchMinor : touchMajor;
            return Math.abs(orientation) > PI_4 ? touchMinor : touchMajor;
        }
        
        public float getToolWidth() {
            return Math.abs(orientation) > PI_8 ? toolMajor : toolMinor;
            return Math.abs(orientation) > PI_4 ? toolMajor : toolMinor;
        }
        
        public float getToolHeight() {
            return Math.abs(orientation) > PI_8 ? toolMinor : toolMajor;
            return Math.abs(orientation) > PI_4 ? toolMinor : toolMajor;
        }
        */
    }
+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

Loading