【android 9】【input】【2.结构体含义】

news2024/11/16 4:33:16

 系列文章目录

可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501


目录

系列文章目录

简介

1. EventHub.h

1.1 结构体

1.1.1 RawEvent

 1.1.2 input_event

1.1.3 input_id

 1.1.4 Device

 1.1.5  epoll_event

 1.1.6  RawAbsoluteAxisInfo

 1.1.7 AxisInfo

1.1.8 inotify_event

1.2 枚举类型

1.2.1 InputDeviceConfigurationFileType

 1.2.2 虚拟键盘的id

1.2.3 添加删除等事件的标志

1.2.4 输入设备class标志

1.2.5 多点触摸

2.InputReader.h

2.1 结构体

2.1.1 KeyDown

 2.1.2 InputReaderConfiguration

2.1.3 Axis

2.1.4 VelocityControlParameters

 2.1.5 parameters

 2.1.6 Calibration

 2.1.7 RawPointerAxes

 2.1.8 DeviceMode

2.2 枚举类型

2.2.1 派发策略标志

 2.2.2 按键source的标志

2.2.3 key事件的标志

2.2.4 EV_xxx类型事件的标志

2.2.5 motion事件边缘触摸标志

2.2.6 motion事件轴的标志

2.2.7 motion事件的发生的工具

2.2.8

 2.2.9

 2.2.10 motion事件的类型

3.InputListener.h

3.1 结构体

3.1.1 NotifyKeyArgs

4. InputDispatcher.h

4.1结构体

4.1.1 InputTarget

 4.1.2 KeyRepeatState

 4.1.3 InputDispatcherConfiguration

 4.1.4 DispatchEntry

4.1.5 Connection

 4.1.6 InjectionState

 4.1.7 InputState

4.1.8 CancelationOptions

4.1.9 PointerCoords

4.2 枚举类型

 4.2.1 Motion事件的标志

4.2.2 InputTargetWaitCause

4.2.3 输入源标志

5.InputTransport.h

5.1 结构体

5.1.1 InputPublisher

5.1.2 InputConsumer

5.1.3 InputMessage

 6.com_android_server_input_InputManagerService.cpp

6.1 结构体

6.1.1 Locked


简介

由于后续篇幅如input启动分析,增删设备事件分析,发送key按键分析中存在大量的结构体,包含了各种信息,为了更好的了解和读懂,此篇,将对大量的结构体和其参数的含义作出解释。


1. EventHub.h

1.1 结构体

1.1.1 RawEvent

//从EventHub检索到的原始事件
struct RawEvent {
    nsecs_t when;//时间
    int32_t deviceId;//事件发生的设备id
    int32_t type;//类型,例如按键事件等
    int32_t code;//扫描码,按键对应的扫描码
    int32_t value;//值,表示按键按下,或者抬起等
};

 1.1.2 input_event

//event结构本身,会将input_event加工成RawEvent,然后交给inputreader处理
struct input_event {
	struct timeval time;//时间
	__u16 type;//类型,例如按键事件等
	__u16 code;//扫描码,按键对应的扫描码
	__s32 value;//值,表示按键按下,或者抬起等
};

1.1.3 input_id

struct input_id {
	__u16 bustype;//类型
	__u16 vendor;//供应商
	__u16 product;//产品
	__u16 version;//版本
};

 1.1.4 Device

struct Device {
        Device* next;//是一个单链表

        int fd; //fd表示此设备的设备节点的描述符,可以从此描述符中读取原始输入事件
        const int32_t id;//id在输入系统中唯一标识这个设备
        const String8 path;//设备节点的路径
        const InputDeviceIdentifier identifier;//厂商信息

        uint32_t classes;//classes表示了设备的类别,键盘设备,触控设备等

        uint8_t keyBitmask[(KEY_MAX + 1) / 8];//事件位掩码,它们详细地描述了设备能够产生的事件类型
        uint8_t absBitmask[(ABS_MAX + 1) / 8];
        uint8_t relBitmask[(REL_MAX + 1) / 8];
        uint8_t swBitmask[(SW_MAX + 1) / 8];
        uint8_t ledBitmask[(LED_MAX + 1) / 8];
        uint8_t ffBitmask[(FF_MAX + 1) / 8];
        uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];

        String8 configurationFile;//配置文件路径,以键值对的形式存储在一个文件中,其路径取决于identfier字段中的厂商信息,这些
       配置信息将会影响InputReader对此设备的事件的加工行为
        PropertyMap* configuration;//会有一个函数从configurationFile读取文件,并将其键值对加载进此map
        VirtualKeyMap* virtualKeyMap;//虚拟键盘映射表。对于键盘类型的设备,这些键盘映射表将原始事件中的键盘扫描码转换为Android定义的
      //的按键值。这个映射表也是从一个文件中加载的,文件路径取决于dentifier字段中的厂商信息 
        KeyMap keyMap;//真实键盘映射表
        sp<KeyCharacterMap> overlayKeyMap;//覆盖健映射表
        sp<KeyCharacterMap> combinedKeyMap;//组合按健映射表

        bool ffEffectPlaying;//力反馈相关,如手柄支持力反馈等
        int16_t ffEffectId; // 

        int32_t controllerNumber;

        int32_t timestampOverrideSec;
        int32_t timestampOverrideUsec;

        Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
        ~Device();

        void close();

        bool enabled; // initially true
        status_t enable();
        status_t disable();
        bool hasValidFd();
        const bool isVirtual; // set if fd < 0 is passed to constructor

        const sp<KeyCharacterMap>& getKeyCharacterMap() const {
            if (combinedKeyMap != NULL) {
                return combinedKeyMap;
            }
            return keyMap.keyCharacterMap;
        }
};

 1.1.5  epoll_event

struct epoll_event {
    __uint32_t events; /* 事件掩码,指明了需要监听的事件种类,
	//常用的事件有EPOLLIN(可读),EPOLLOUT(可写),EPOLLERR(描述符发生错误),EPOLLHUP(描述符被挂起)
   epoll_data_t data; /* 使用者自定义的数据,当此事件发生时该数据将原封不动地返回给使用者 */
};

 1.1.6  RawAbsoluteAxisInfo

struct RawAbsoluteAxisInfo {
    bool valid; // 此项信息是否受到输入设备的支持,如果信息有效,则为true,否则为false

    int32_t minValue;  // 此项信息的最小值
    int32_t maxValue;  // 此项信息的最大值
    int32_t flat;      // 中心平面位置,例如flat==8表示中心在-8和8之间
    int32_t fuzz;      // 容错范围。表示因干扰所导致的最大偏移量,例如fuzz==4意味着干扰信息导致的值为+/-4
    int32_t resolution; // 精度,表示在1毫米的范围中的解析点的数量 
	
	//例如,对设备的X坐标这项信息而言,RawAbsoluteAxisInfo的minValue和maxValue表示了事件上报的X坐标范围,
	//Resolution则表示传感器在每毫米距离中可以产生的X坐标点 的数量(ppm)。
	//X坐标与Y坐标的这些技术指标构建了传感器的物理坐标系。而对压力值这项信息而言,
	//如果其RawAbsoluteAxisInfo的valid值为false,则表示此设备不支持识别压力值。
	//当然,这些字段并不是对所有类型的信息都有效,例如对于传感器所支持的触控点数量这项信息,
	//仅有valid和maxValue两个字段有效,valid为true表示设备支持通过slot协议进行触控点索引的识别,
	//而maxValue则表示最大触控点的数量为maxValue+1。

    inline void clear() {
        valid = false;
        minValue = 0;
        maxValue = 0;
        flat = 0;
        fuzz = 0;
        resolution = 0;
    }
};

 1.1.7 AxisInfo

源路径为:/frameworks/native/include/input/KeyLayoutMap.h

struct AxisInfo {
    enum Mode {
        // 直接报告轴值。
        MODE_NORMAL = 0,
        // 报告前应反转轴值。
        MODE_INVERT = 1,
        // 轴值应拆分为两个轴
        MODE_SPLIT = 2,
    };

    // Axis mode.
    Mode mode;

    // Axis id.
    // 分割时,这是用于小于分割位置的值的轴。
    int32_t axis;

    // 分割时,这是用于高于分割位置之后的值的轴。
    int32_t highAxis;

    // 拆分值,如果未拆分,则为0。
    int32_t splitValue;

    // The flat value, or -1 if none.
    int32_t flatOverride;

    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
    }
};

1.1.8 inotify_event

struct inotify_event
{
    int wd;          /* 事件对应的Watch对象的描述符.  */
    uint32_t mask;   /* 事件类型,例如文件被删除,此处值为IN_DELETE.  */
    uint32_t cookie; /* 同步两个事件的缓存  */
    uint32_t len;    /* name字段的长度  */
    char name __flexarr;
    // 可变长的字段,用于存储产生此事件的文件路径 * /
};

1.2 枚举类型

1.2.1 InputDeviceConfigurationFileType

此类型源路径为:/frameworks/native/include/input/InputDevice.h

enum InputDeviceConfigurationFileType {
			INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file *//idc文件,主要用于触摸屏配置
			INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file *//主要用于键盘的扫描码和keycode的转化
			INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file *///.kcm"文件意为按键字符映射文件,作用是将 Android按键代码与修饰符的组合映射到 Unicode字符

 1.2.2 虚拟键盘的id

enum {
    
    VIRTUAL_KEYBOARD_ID = -1,// 始终存在的特殊虚拟键盘的设备id
    BUILT_IN_KEYBOARD_ID = 0,//内置键盘的设备id(如果有)。
};

1.2.3 添加删除等事件的标志

// 添加或删除设备时生成的合成原始事件类型代码。
enum {
        // 添加设备时发送。
        DEVICE_ADDED = 0x10000000,
        // 删除设备时发送。
        DEVICE_REMOVED = 0x20000000,
        //当报告了最近扫描中添加/删除的所有设备时发送
		//此事件始终至少发送一次。
        FINISHED_DEVICE_SCAN = 0x30000000,

        FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
};

1.2.4 输入设备class标志

/*
 * Input device classes.
 */
enum {
    /* 输入设备是键盘或有按钮 */
    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,

    /* 输入设备是字母数字键盘(不仅仅是拨号盘). */
    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,

    /* 输入设备是触摸屏或触摸板(单触或多触). */
    INPUT_DEVICE_CLASS_TOUCH         = 0x00000004,

    /* 输入设备是光标设备,如轨迹球或鼠标. */
    INPUT_DEVICE_CLASS_CURSOR        = 0x00000008,

    /* 输入设备为多点触摸屏. */
    INPUT_DEVICE_CLASS_TOUCH_MT      = 0x00000010,

    /* 输入设备是一个方向键盘(表示键盘,具有DPAD键). */
    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,

    /* 输入设备是一个游戏板(意味着键盘有按钮键). */
    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,

    /* 输入设备有开关. */
    INPUT_DEVICE_CLASS_SWITCH        = 0x00000080,

    /* 输入设备是一个操纵杆(意味着游戏板具有操纵杆绝对轴). */
    INPUT_DEVICE_CLASS_JOYSTICK      = 0x00000100,

    /* 输入设备有一个可控震源(支持力反馈). */
    INPUT_DEVICE_CLASS_VIBRATOR      = 0x00000200,

    /* 输入设备有麦克风. */
    INPUT_DEVICE_CLASS_MIC           = 0x00000400,

    /* 输入设备是一个外部手写笔. */
    INPUT_DEVICE_CLASS_EXTERNAL_STYLUS = 0x00000800,

    /* 输入设备有一个滚轮式设备*/
    INPUT_DEVICE_CLASS_ROTARY_ENCODER = 0x00001000,

    /* 输入设备是虚拟的(不是真实的设备)*/
    INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,

    /* 输入设备为外部,非内置. */
    INPUT_DEVICE_CLASS_EXTERNAL      = 0x80000000,

    /* 输入设备是第三方设备1。. */
    INPUT_DEVICE_CLASS_TERTIARY1      = 0x20000000,

    /* 输入设备是第三方设备2 */
    INPUT_DEVICE_CLASS_TERTIARY2      = 0x10000000,
};

1.2.5 多点触摸

#define ABS_MT_SLOT		0x2f	/* MT slot being modified */
#define ABS_MT_TOUCH_MAJOR	0x30	/*触摸椭圆的长轴 */
#define ABS_MT_TOUCH_MINOR	0x31	/* touching椭圆的短轴(如果是圆形,则省略) */
#define ABS_MT_WIDTH_MAJOR	0x32	/* approaching椭圆的长轴 */
#define ABS_MT_WIDTH_MINOR	0x33	/* approaching椭圆的短轴(如果是圆形,则省略) */
#define ABS_MT_ORIENTATION	0x34	/* 椭圆方向 */
#define ABS_MT_POSITION_X	0x35	/* 椭圆中心X位置 */
#define ABS_MT_POSITION_Y	0x36	/* 椭圆中心Y位置 */
#define ABS_MT_TOOL_TYPE	0x37	/* 触摸设备类型 */
#define ABS_MT_BLOB_ID		0x38	/* 将一组数据包 as a blob */
#define ABS_MT_TRACKING_ID	0x39	/* 最初触摸的唯一ID */
#define ABS_MT_PRESSURE		0x3a	/* 触摸区域的压力 */
#define ABS_MT_DISTANCE		0x3b	/* Contact hover distance,接触悬停距离 */

2.InputReader.h

2.1 结构体

2.1.1 KeyDown

 struct KeyDown {
        int32_t keyCode;//按键code
        int32_t scanCode;//扫描玛
    };

 2.1.2 InputReaderConfiguration

struct InputReaderConfiguration {
    // 描述已发生的changes
    enum {
        // The pointer 速度改变
        CHANGE_POINTER_SPEED = 1 << 0,

        // The pointer 手势控制已改变.
        CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,

        // 显示大小或方向已改变
        CHANGE_DISPLAY_INFO = 1 << 2,

        // 可见触摸选项已改变
        CHANGE_SHOW_TOUCHES = 1 << 3,

        // 键盘布局必须重新加载
        CHANGE_KEYBOARD_LAYOUTS = 1 << 4,

        // 对于某些设备,由提供的设备名称别名可能已更改。
        CHANGE_DEVICE_ALIAS = 1 << 5,

        //位置校准矩阵已更改
        CHANGE_TOUCH_AFFINE_TRANSFORMATION = 1 << 6,

        // 外部手写笔的存在已更改
        CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7,

        // The pointer获取模式已更改
        CHANGE_POINTER_CAPTURE = 1 << 8,

        // 禁用的输入设备(disabledDevices)已更改。
        CHANGE_ENABLED_STATE = 1 << 9,

        // 所有设备必须重新打开
        CHANGE_MUST_REOPEN = 1 << 31,
    };

  //获取触摸屏幕后禁用虚拟键的时间量,以过滤由于在屏幕边缘附近滑动手势或轻击而导致的意外虚拟键按下。可以为0以禁用该功能。
  //比如:触摸了手机返回键边缘的屏幕
    nsecs_t virtualKeyQuietTime;

    // 平台的排除设备名称。将忽略具有这些名称的设备。
    Vector<String8> excludedDeviceNames;

    // 鼠标指针移动的速度控制参数。
    VelocityControlParameters pointerVelocityControlParameters;

    // 鼠标滚轮移动的速度控制参数。
    VelocityControlParameters wheelVelocityControlParameters;

    //如果启用了pointer手势,则为True。
    bool pointerGesturesEnabled;

    // 某些pointer手势转换之间的安静时间。
	//在开始新手势之前,允许所有手指或按钮安置到稳定状态的时间。
    nsecs_t pointerGestureQuietInterval;

    //在拖动过程中,指针必须移动的最小速度,以便我们考虑将活动触摸指针切换到它。
	//设置此阈值是为了避免由于手指放在触摸板上(可能只是按下它)产生的干扰信息而切换。
    float pointerGestureDragMinSwitchSpeed; // in pixels per second

    //轻触手势延迟时间。
	//下降和上升之间的时间必须小于此值,才能视为轻敲。
    nsecs_t pointerGestureTapInterval;

    //点击拖动手势延迟时间。
	//上一次点击抬起和下一次点击按下之间的时间必须小于此时间,才能被视为拖曳。否则,上一次点击结束,新的点击开始。
	//请注意,上一次敲击将在整个持续时间内按住,因此此间隔必须短于长按超时。
    nsecs_t pointerGestureTapDragInterval;

    // 允许指针从初始位置向下移动到上的距离(以像素为单位),仍然称为轻敲。
    float pointerGestureTapSlop; // in pixels

    // 第一个触摸点按下到初始质心上的时间。
	//这是为了有足够的时间来处理用户几乎同时但不完全同时放下两根手指的情况。
    nsecs_t pointerGestureMultitouchSettleInterval;

    // 当至少有两个指针从起始位置移动了至少这么远时,就会从PRESS(按压)模式转换到SWIPE(划动)或FREEFORM(自由)手势模式。
    float pointerGestureMultitouchMinDistance; // in pixels

    // 只有当两个矢量之间的角度余弦大于或等于该值时,才能从PRESS(按压)姿势模式转换为SWIPE(滑动)姿势模式,这表明矢量方向相同。
    float pointerGestureSwipeTransitionAngleCosine;

    // 只有当手指相对于触摸板的对角线尺寸不超过这个距离时,才能从按压手势模式转换为滑动手势模式。
	//例如,0.5的比例意味着手指之间的间隔必须不超过触摸板对角线大小的一半。
    float pointerGestureSwipeMaxWidthRatio;

    // 相对于显示器大小的手势移动速度。
    float pointerGestureMovementSpeedRatio;

    //相对于显示器大小的手势缩放速度
	//当手指主要相对于彼此移动时,缩放速度适用
	//以执行缩放手势或类似动作。
    float pointerGestureZoomSpeedRatio;

    // True可将触摸屏上的触摸位置显示为点。
    bool showTouches;

    // True if pointer capture is enabled.
    bool pointerCapture;

    // 当前禁用的设备
    SortedVector<int32_t> disabledDevices;

};

2.1.3 Axis

struct Axis {
        RawAbsoluteAxisInfo rawAxisInfo;
        AxisInfo axisInfo;

        bool explicitlyMapped; // 如果轴明确指定了轴id,则为true

        float scale;   // 从raw 到标准化的比例值
        float offset;  // 缩放标准化后要添加的偏移量
        float highScale;  // high split的从raw 到标准化的比例值
        float highOffset; //  high split的缩放标准化后要添加的偏移量

        float min;        // 标准化范围的最小值
        float max;        // 标准化范围的最大值
        float flat;       // 标准化平面区域大小
        float fuzz;       // 标准化的容错范围
        float resolution; // 标准化精度(单位/mm)

        float filter;  // filter out small variations of this size
        float currentValue; // 
        float newValue; // most recent value
        float highCurrentValue; //high split的当前值
        float highNewValue; // high split的most recent value

        void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
                bool explicitlyMapped, float scale, float offset,
                float highScale, float highOffset,
                float min, float max, float flat, float fuzz, float resolution) {
            this->rawAxisInfo = rawAxisInfo;
            this->axisInfo = axisInfo;
            this->explicitlyMapped = explicitlyMapped;
            this->scale = scale;
            this->offset = offset;
            this->highScale = highScale;
            this->highOffset = highOffset;
            this->min = min;
            this->max = max;
            this->flat = flat;
            this->fuzz = fuzz;
            this->resolution = resolution;
            this->filter = 0;
            resetValue();
        }

        void resetValue() {
            this->currentValue = 0;
            this->newValue = 0;
            this->highCurrentValue = 0;
            this->highNewValue = 0;
        }
};

2.1.4 VelocityControlParameters

//指定移动的加速度相关的参数
struct VelocityControlParameters {
	//在应用任何其他速度控制因子之前,与原始速度增量相乘的比例因子。
	//应使用比例因子使输入设备分辨率(例如每英寸计数)与输出设备分辨率(如每英寸像素)相适应。
    float scale;

    //开始施加加速度时的缩放速度。
	//该值为在没有任何加速度的情况下进行的小的精确运动建立了低速状态的上限。
    float lowThreshold;


    //应用最大加速度时的缩放速度。
    float highThreshold;


    //加速度系数
    float acceleration;
};

 2.1.5 parameters

	struct parameters {
        enum devicetype {
           device_type_touch_screen,//触摸屏
            device_type_touch_pad,//触摸板,比如笔记本电脑的触摸板
            device_type_touch_navigation,//触摸导航键,以前智能手机的三个按键
            device_type_pointer,//指针,鼠标
        };

        devicetype devicetype;
        bool hasassociateddisplay;//是否有关联的display
        bool associateddisplayisexternal;//是否关联的display是外部的
        bool orientationaware;//方位感知
        bool hasbuttonunderpad;//触摸板是否有按键
        string8 uniquedisplayid;//显示的屏幕id

        enum gesturemode {
            gesture_mode_single_touch,//多点触摸
            gesture_mode_multi_touch,//单点触摸
        };
        gesturemode gesturemode;

       bool wake;
} mparameters;

 2.1.6 Calibration

// 不可变的校准参数。
struct Calibration {
        // 大小
        enum SizeCalibration {
            SIZE_CALIBRATION_DEFAULT,//默认值大小
            SIZE_CALIBRATION_NONE,//大小为空
            SIZE_CALIBRATION_GEOMETRIC,
            SIZE_CALIBRATION_DIAMETER,
            SIZE_CALIBRATION_BOX,
            SIZE_CALIBRATION_AREA,
        };

        SizeCalibration sizeCalibration;

        bool haveSizeScale;
        float sizeScale;//大小缩放比例
        bool haveSizeBias;
        float sizeBias;//大小偏差
        bool haveSizeIsSummed;
        bool sizeIsSummed;

        //压力
        enum PressureCalibration {
            PRESSURE_CALIBRATION_DEFAULT,
            PRESSURE_CALIBRATION_NONE,
            PRESSURE_CALIBRATION_PHYSICAL,//压力校准_物理
            PRESSURE_CALIBRATION_AMPLITUDE,//压力校准_振幅
        };

        PressureCalibration pressureCalibration;
        bool havePressureScale;
        float pressureScale;

        // 方向
        enum OrientationCalibration {
            ORIENTATION_CALIBRATION_DEFAULT,
            ORIENTATION_CALIBRATION_NONE,
            ORIENTATION_CALIBRATION_INTERPOLATED,
            ORIENTATION_CALIBRATION_VECTOR,
        };

        OrientationCalibration orientationCalibration;

        // 距离
        enum DistanceCalibration {
            DISTANCE_CALIBRATION_DEFAULT,
            DISTANCE_CALIBRATION_NONE,
            DISTANCE_CALIBRATION_SCALED,
        };

        DistanceCalibration distanceCalibration;
        bool haveDistanceScale;
        float distanceScale;
		
		//范围
        enum CoverageCalibration {
            COVERAGE_CALIBRATION_DEFAULT,
            COVERAGE_CALIBRATION_NONE,
            COVERAGE_CALIBRATION_BOX,
        };

        CoverageCalibration coverageCalibration;

        inline void applySizeScaleAndBias(float* outSize) const {
            if (haveSizeScale) {
                *outSize *= sizeScale;
            }
            if (haveSizeBias) {
                *outSize += sizeBias;
            }
            if (*outSize < 0) {
                *outSize = 0;
            }
        }
} mCalibration;

 2.1.7 RawPointerAxes

//来自驱动器的原始轴信息. 
stuct RawPointerAxes {
    RawAbsoluteAxisInfo x;
    RawAbsoluteAxisInfo y;
    RawAbsoluteAxisInfo pressure;//压力信息
    RawAbsoluteAxisInfo touchMajor;//触摸主要的轴
    RawAbsoluteAxisInfo touchMinor;//触摸次要
    RawAbsoluteAxisInfo toolMajor;//工具主要
    RawAbsoluteAxisInfo toolMinor;//工具次要
    RawAbsoluteAxisInfo orientation;//方向
    RawAbsoluteAxisInfo distance;//距离
    RawAbsoluteAxisInfo tiltX;//倾斜x
    RawAbsoluteAxisInfo tiltY;//倾斜y
    RawAbsoluteAxisInfo trackingId;//跟踪id
    RawAbsoluteAxisInfo slot;//slot

    RawPointerAxes();
    void clear();
};

 2.1.8 DeviceMode

enum DeviceMode {
        DEVICE_MODE_DISABLED, // 禁用inpu设备
        DEVICE_MODE_DIRECT, // direct mapping (touchscreen),直接映射
        DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad),未缩放映射
        DEVICE_MODE_NAVIGATION, // 触摸导航,伪缩放映射
        DEVICE_MODE_POINTER, // 鼠标指针映射
};

2.2 枚举类型

2.2.1 派发策略标志

/*
 * 与input分发系统中的事件一起流动的标志,有助于某些策略决策,例如从设备睡眠中醒来.
 *
 * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
 */
enum {
    /* These flags originate in RawEvents and are generally set in the key map.
     * NOTE: If you want a flag to be able to set in a keylayout file, then you must add it to
     * InputEventLabels.h as well. */

    // 指示事件应唤醒设备
    POLICY_FLAG_WAKE = 0x00000001,

    // Indicates that the key is virtual, such as a capacitive button, and should
    // generate haptic feedback.  Virtual keys may be suppressed for some time
    // after a recent touch to prevent accidental activation of virtual keys adjacent
    // to the touch screen during an edge swipe.
	//指示按键是虚拟的,如电容式按钮,并应生成触觉反馈。虚拟键可以在最近的触摸之后被抑制一段时间,以防止在边缘滑动期间与触摸屏相邻的虚拟键的意外激活。
    POLICY_FLAG_VIRTUAL = 0x00000002,

    // Indicates that the key is the special function modifier.
	//指示键是特殊函数修饰符
    POLICY_FLAG_FUNCTION = 0x00000004,

    // Indicates that the key represents a special gesture that has been detected by
    // the touch firmware or driver.  Causes touch events from the same device to be canceled.
	表示按键代表触摸固件或驱动程序检测到的特殊手势。导致取消来自同一设备的触摸事件。
    POLICY_FLAG_GESTURE = 0x00000008,

    POLICY_FLAG_RAW_MASK = 0x0000ffff,

    /* These flags are set by the input dispatcher. */

    // Indicates that the input event was injected.
	//指示输入事件已注入。
    POLICY_FLAG_INJECTED = 0x01000000,

    // Indicates that the input event is from a trusted source such as a directly attached
    // input device or an application with system-wide event injection permission.
	//指示输入事件来自受信任的源,例如直接连接的输入设备或具有系统范围事件注入权限的应用程序。
    POLICY_FLAG_TRUSTED = 0x02000000,

    //Indicates that the input event has passed through an input filter.
	//指示输入事件已通过输入筛选器。
    POLICY_FLAG_FILTERED = 0x04000000,

    // Disables automatic key repeating behavior.
	//禁用自动按键重复行为
    POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,

    /* These flags are set by the input reader policy as it intercepts each event. */

    // Indicates that the device was in an interactive state when the
    // event was intercepted.
	//指示当截获事件时设备处于交互状态
    POLICY_FLAG_INTERACTIVE = 0x20000000,

    // Indicates that the event should be dispatched to applications.
    // The input event should still be sent to the InputDispatcher so that it can see all
    // input events received include those that it will not deliver.
	//指示应将事件分派给应用程序。输入事件仍应发送到InputDispatcher,以便它可以看到所有
	//收到的输入事件包括它不会传递的事件
    POLICY_FLAG_PASS_TO_USER = 0x40000000,
};

 2.2.2 按键source的标志

enum {
    /** unknown */
    AINPUT_SOURCE_UNKNOWN = 0x00000000,

    /** 键盘 */
    AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,  100000001
    /** 方向垫,允许用户在四个主要方向(上、下、左、右)上进行选择或移动。例如手柄上下左右 */
    AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
    /** 游戏手柄 */
    AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
    /** 触摸屏 */
    AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
    /** 鼠标 */
    AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
    /** 手写笔 */
    AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
    /** 蓝牙手写笔 */
    AINPUT_SOURCE_BLUETOOTH_STYLUS = 0x00008000 | AINPUT_SOURCE_STYLUS,
    /** 轨迹球 */
    AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
    /** 鼠标的输入模式,相对模式 在相对模式下,鼠标(或类似的指向设备)的移动不是基于绝对的屏幕坐标,
	而是基于相对于上一次移动位置的相对变化。具体来说,当你移动鼠标时,系统不是记录鼠标指针在屏幕上的绝对位置,
	而是记录鼠标从上次读取位置移动了多少个单位(例如,多少像素)。*/
    AINPUT_SOURCE_MOUSE_RELATIVE = 0x00020000 | AINPUT_SOURCE_CLASS_NAVIGATION,
    /** 触摸面板 */
    AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
    /** 触摸滚轮 */
    AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
    /** 操纵杆 */
    AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
    /** 旋转编码器是一种用于测量或控制旋转位置的设备。它通常包含一个可旋转的轴和一个或多个输出,这些输出可以指示轴旋转的方向和/或旋转的角度 */
    AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,

    /** 任何 */
    AINPUT_SOURCE_ANY = 0xffffff00,
};

2.2.3 key事件的标志

enum {
    /** This mask is set if the device woke because of this key event. */
	//如果设备因此key事件而唤醒,则设置此掩码
	/*当用户按下某个按键(例如,电源键或特定硬件按钮)时,如果设备当时处于休眠或待机状态,
	这个按键事件不仅会被生成并传递给应用程序进行处理,而且它还会被标记为FLAG_WOKE_HERE。
	这个标志对于应用程序来说可能是有用的,因为它可以帮助应用程序了解用户是如何唤醒设备的,并据此采取适当的操作。*/
    AKEY_EVENT_FLAG_WOKE_HERE = 0x1,

    /** This mask is set if the key event was generated by a software keyboard. */
	//如果按键事件是由软件键盘生成的,则设置此掩码
	/*软键盘是一个显示在屏幕上的虚拟键盘,用于在无法或不方便使用物理键盘的设备(如智能手机和平板电脑)上进行文本输入。
	当用户在文本输入框中点击或触摸时,软键盘通常会自动弹出。*/
    AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,

    
	//如果我们不希望key事件导致我们离开触摸模式,则会设置此掩码
	/*用于指示在按键事件发生时是否保持触摸模式。在Android中,触摸模式通常与触摸屏输入相关,
	当用户在屏幕上进行触摸或滑动操作时,系统会进入触摸模式,并相应地调整某些行为(如滚动和焦点处理)。
	当某个按键事件被标记为 FLAG_KEEP_TOUCH_MODE 时,这意味着即使按键事件发生了,系统也不应该退出触摸模式。
	这在某些场景下可能是有用的,比如当你想在按键事件发生时保持触摸输入的有效性或继续处理触摸事件时。*/
    AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,

    /*
	如果已知事件来自系统的受信任部分,则会设置此掩码。也就是说,已知事件来自用户,不可能被第三方组件欺骗。
     */
    AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,

    /*
	此掩码用于兼容性,以识别输入键已自动标记为“下一步”或“完成”的输入法中的输入键。
	这允许TextView将这些输入键作为旧应用程序的正常输入键进行调度,但在接收它们时仍会执行适当的操作。*/
    AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,

    /**
	//当与向上按键事件关联时,这表示按键压力已被取消。
	//通常,这与虚拟触摸屏按键一起使用,用户可以从虚拟按键区域滑到显示器上:
	//在这种情况下,应用程序将收到取消事件,不应执行通常与按键相关的操作。
	//请注意,要使其工作,应用程序在收到向上键或长按超时到期之前无法对键执行操作。
     */
    AKEY_EVENT_FLAG_CANCELED = 0x20,

    /**
	//*此按键事件由虚拟(屏幕上)硬按键区域生成。

	//通常,这是触摸屏的一个区域,位于常规显示器之外,专门用于“硬件”按钮。
     */
    AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,

    /**
	//此标志是为长按超时后发生的第一次按键重复设置的。
     */
    AKEY_EVENT_FLAG_LONG_PRESS = 0x80,

    /**
     * //取消长按
     */
    AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,

    /**
     * Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
     * tracked from its initial down.  That is, somebody requested that tracking
     * started on the key down and a long press has not caused
     * the tracking to be canceled.
     */
    AKEY_EVENT_FLAG_TRACKING = 0x200,

    /**
     * Set when a key event has been synthesized to implement default behavior
     * for an event that the application did not handle.
     * Fallback key events are generated by unhandled trackball motions
     * (to emulate a directional keypad) and by certain unhandled key presses
     * that are declared in the key map (such as special function numeric keypad
     * keys when numlock is off).
     */
    AKEY_EVENT_FLAG_FALLBACK = 0x400,
};

2.2.4 EV_xxx类型事件的标志

#define EV_SYN			0x00//同步类型事件,用于事件间的分割标志。事件可能按时间或空间进行分割
#define EV_KEY			0x01//按键类型事件
#define EV_REL			0x02//相对坐标类型事件,用来描述相对坐标轴上数值的变化,例如:鼠标向左方移动了5个单位。
#define EV_ABS			0x03//绝对坐标类型事件,用来描述相对坐标轴上数值的变化,例如:描述触摸屏上坐标的值。
#define EV_MSC			0x04//杂项类型事件,当不能匹配现有的类型时,使用该类型进行描述。
#define EV_SW			0x05//开关类型事件,用来描述具备两种状态的输入开关
#define EV_LED			0x11//LED灯类型事件.用于控制设备上的LED灯的开和关。
#define EV_SND			0x12//声音类型事件
#define EV_REP			0x14//重复值类型事件
#define EV_FF			0x15//力反馈类型事件
#define EV_PWR			0x16//像是电源类型事件
#define EV_FF_STATUS		0x17
#define EV_MAX			0x1f//最大数量
#define EV_CNT			(EV_MAX+1)

//SYN_REPORT: 当多个输入数据在同一时间发生变化时,SYN_REPORT用于把这些数据进行打包和包同步。
例如,一次鼠标的移动可以上报REL_X和REL_Y两个数值,然后发出一个SYN_REPORT。下一次鼠标移动可以再次发出REL_X和REL_Y两个数值,然后经跟这另一个SYN_REPORT。

2.2.5 motion事件边缘触摸标志

/**
 * Motion event边缘触摸标志。
 */
enum {
    /** 无交叉的边. */
    AMOTION_EVENT_EDGE_FLAG_NONE = 0,

    /** 指示运动事件与屏幕顶部边缘相交的标志。. */
    AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,

    /** 指示运动事件与屏幕底部边缘相交的标志. */
    AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,

    /** 指示运动事件与屏幕最左端边缘相交的标志. */
    AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,

    /** 指示运动事件与屏幕最右端边缘相交的标志. */
    AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
};

2.2.6 motion事件轴的标志

/**
	//轴常量:motion事件的Z轴。
	//对于操纵杆,报告操纵杆的绝对Z位置。
	//该值规格化为-1.0(高)到1.0(低)的范围。
	//在带有两个模拟操纵杆的游戏板上,此轴通常被重新解释为报告第二个操纵杆的绝对X位置
    AMOTION_EVENT_AXIS_Z = 11,
	
	//轴常量:motion事件的X旋转轴。
	//对于操纵杆,报告关于X轴的绝对旋转角度。
	//该值规格化为-1.0(逆时针)到1.0(顺时针)的范围。
    AMOTION_EVENT_AXIS_RX = 12,
	
	//轴常量:motion事件的Y旋转轴。
	//对于操纵杆,报告绕Y轴的绝对旋转角度。
	//该值规格化为-1.0(逆时针)到1.0(顺时针)的范围。
    AMOTION_EVENT_AXIS_RY = 13,

	//轴常量:运动事件的Z旋转轴。
	//-对于操纵杆,报告关于Z轴的绝对旋转角度。
	//该值规格化为-1.0(逆时针)到1.0(顺时针)的范围。
	//在带有两个模拟操纵杆的游戏板上,此轴通常被重新解释为报告第二个操纵杆的绝对Y位置。
    AMOTION_EVENT_AXIS_RZ = 14,
	
	//轴常数:运动事件的十字X轴。
	//对于操纵杆,报告定向帽子控制的绝对X位置。
	//该值规格化为-1.0(左)到1.0(右)的范围。
    AMOTION_EVENT_AXIS_HAT_X = 15,
	
	//轴常量:运动事件的十字Y轴。
	//对于操纵杆,报告定向十字控制的绝对Y位置。
	//该值规格化为-1.0(向上)到1.0(向下)的范围。
    AMOTION_EVENT_AXIS_HAT_Y = 16,
	
    // 轴常量:运动事件的左触发轴。
	//对于操纵杆,报告左触发控制器的绝对位置。
	//该值规格化为0.0(释放)到1.0(完全按下)的范围。
	
    AMOTION_EVENT_AXIS_LTRIGGER = 17,
    //轴常量:运动事件的右触发轴。
	//对于操纵杆,报告右触发控制器的绝对位置。
	//该值规格化为0.0(释放)到1.0(完全按下)的范围。
	
    AMOTION_EVENT_AXIS_RTRIGGER = 18,
    //轴常数:运动事件的油门轴。
	//*-对于操纵杆,报告油门控制的绝对位置。
	//该值规格化为0.0(完全打开)到1.0(完全关闭)的范围。
	
    AMOTION_EVENT_AXIS_THROTTLE = 19,
	//轴常数:运动事件的方向舵轴。
	//*-对于操纵杆,报告方向舵控制的绝对位置。
	//*该值规格化为-1.0(左转)到1.0(右转)的范围。
	
    AMOTION_EVENT_AXIS_RUDDER = 20,
	//轴常量:运动事件的轮子轴。
	//*-对于操纵杆,报告方向盘控制的绝对位置。
	//该值规格化为-1.0(左转)到1.0(右转)的范围。
	
    AMOTION_EVENT_AXIS_WHEEL = 21,
	//轴常数:运动事件的汽油轴。
	//-对于操纵杆,报告气体(加速器)控制的绝对位置。
	//*该值规格化为0.0(无加速度)的范围*至1.0(最大加速度)
    AMOTION_EVENT_AXIS_GAS = 22,
	
	//轴常数:运动事件的制动轴。
	//对于操纵杆,报告制动控制装置的绝对位置。
	//该值标准化为0.0(无制动)到1.0(最大制动)的范围。
	
    AMOTION_EVENT_AXIS_BRAKE = 23,
     //按下手势期间发生了更改(在AMOTION_EVENT_ACTION_DOWN和AMOTION_EVENT_ACTION_UP之间)。
	 motion包含最近的点,以及自最近一次按下下或move事件以来的任何中间点。
	AMOTION_EVENT_ACTION_MOVE = 2,
    //发生了更改,但poniter未down(与AMOTION_EVENT_ACTION_MOVE不同)。
	//该运动包含最近的点以及自上次悬停移动事件以来的任何中间点。
    AMOTION_EVENT_ACTION_HOVER_MOVE = 7,

2.2.7 motion事件的发生的工具

//标识工具类型的常量。有关每种工具类型的说明,请参阅MotionEvent类的文档。
enum {
    /** unknown */
	AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0,
	/** 手指 */
	AMOTION_EVENT_TOOL_TYPE_FINGER = 1,
	/** 触笔 */
	AMOTION_EVENT_TOOL_TYPE_STYLUS = 2,
	/** 鼠标 */
	AMOTION_EVENT_TOOL_TYPE_MOUSE = 3,
	/** eraser */
	AMOTION_EVENT_TOOL_TYPE_ERASER = 4,
};

2.2.8

enum {
	//当motion事件未与任何display关联时使用。
	ADISPLAY_ID_NONE = -1,
	//默认的display id */
	ADISPLAY_ID_DEFAULT = 0,
};

 2.2.9

enum {

    AINPUT_KEYBOARD_TYPE_NONE = 0,
    // 无字母的键盘按键
    AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
    // 有字母的键盘按键
    AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
};

 2.2.10 motion事件的类型

/** Motion event actions */
enum {
    /** 标识motion code本身的位掩码 ,即所有的motion都有这个位掩码*/
    AMOTION_EVENT_ACTION_MASK = 0xff,

    
	//获取当前指针索引,在多点触控交互中发生
    AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,

  
	//当屏幕检测到第一个触点按下之后就会触发的事件,表示motion开始按下,包含最初按下的位置
    AMOTION_EVENT_ACTION_DOWN = 0,


	//最后一个触摸点motion抬起,该动作包含最终释放位置以及自上次向下或移动事件以来的任何中间点。
    AMOTION_EVENT_ACTION_UP = 1,


	 //motion移动,该动议包含最近的一点,以及自上次向下或移动事件以来的任何中间点
    AMOTION_EVENT_ACTION_MOVE = 2,

	//AMOTION_EVENT_ACTION_CANCEL的含义是触摸事件被取消。
	//当父容器拦截了触摸事件或者发生了意外情况(如突然来电),当前的触摸事件序列会被取消,即触摸事件的处理被中断。
	//ACTION_CANCEL事件通常在ACTION_DOWN之后触发,用于通知应用程序取消当前的触摸操作。
    AMOTION_EVENT_ACTION_CANCEL = 3,


	//AMOTION_EVENT_ACTION_OUTSIDE的含义是用户触碰超出了正常的UI边界。
    AMOTION_EVENT_ACTION_OUTSIDE = 4,

	//AMOTION_EVENT_ACTION_POINTER_DOWN的含义是当屏幕上已经有至少一个点被按下的情况下,又有新的点被按下时触发的事件。
	//在多点触控的交互中,MotionEvent.ACTION_POINTER_DOWN事件用于标识除了最初按下的点之外的其他点的按下动作。
	//这个事件与MotionEvent.ACTION_DOWN的主要区别在于,ACTION_DOWN是当屏幕上首次有触点按下时触发
	//而ACTION_POINTER_DOWN是在屏幕上已经有至少一个触点被按下之后,再有其他触点被按下时触发。
    AMOTION_EVENT_ACTION_POINTER_DOWN = 5,

	//AMOTION_EVENT_ACTION_POINTER_UP的含义是当屏幕上有多个点被按住,其中一个点被松开时触发的事件。
	//这个事件与ACTION_UP的区别在于,ACTION_UP是在最后一个点被松开时触发。
	//而ACTION_POINTER_UP则是在多个触摸点中的一个触摸点消失时(此时,还有其他触摸点存在,即用户还有其他手指触摸屏幕)触发。
    AMOTION_EVENT_ACTION_POINTER_UP = 6,

	//AMOTION_EVENT_ACTION_HOVER_MOVE表示的是当鼠标指针(或类似的设备,比如支持悬停功能的触摸屏笔)在视图上方移动,但没有实际接触到屏幕时触发的事件。
	//这个事件是Android为支持非触摸输入设备(如鼠标和触摸板)而引入的。当鼠标指针在屏幕上方移动,但没有按下任何按钮时,系统就会发送ACTION_HOVER_MOVE事件。
	//如果用户在悬停的同时按下了鼠标按钮,那么系统可能会发送其他类型的事件,如ACTION_DOWN、ACTION_MOVE等。
    AMOTION_EVENT_ACTION_HOVER_MOVE = 7,

	//AMOTION_EVENT_ACTION_SCROLL的含义是非触摸滚动,这个事件主要由鼠标、滚轮、轨迹球等设备触发。
	//例如鼠标滚轮滚动或轨迹球移动等。这些事件在滚动条、地图、图片查看器
    AMOTION_EVENT_ACTION_SCROLL = 8,

    //AMOTION_EVENT_ACTION_HOVER_ENTER的含义是当鼠标指针(或类似的设备,比如支持悬停功能的触摸屏笔)从屏幕外部移动到视图上方,即进入视图的有效区域时触发的事件。
	//这个事件是Android为支持非触摸输入设备(如鼠标和触摸板)而引入的。当鼠标指针从屏幕外部移动进入某个视图区域时,系统就会发送ACTION_HOVER_ENTER事件
    AMOTION_EVENT_ACTION_HOVER_ENTER = 9,

    //AMOTION_EVENT_ACTION_HOVER_EXIT的含义是当鼠标指针(或类似的设备,比如支持悬停功能的触摸屏笔)从视图上方移动到屏幕外部,即离开视图的有效区域时触发的事件。
    AMOTION_EVENT_ACTION_HOVER_EXIT = 10,

	//一个或者多个按键被按下
    AMOTION_EVENT_ACTION_BUTTON_PRESS = 11,

    /* One or more buttons have been released. */
	//一个或者多个按键被抬起
    AMOTION_EVENT_ACTION_BUTTON_RELEASE = 12,
};

3.InputListener.h

3.1 结构体

3.1.1 NotifyKeyArgs

struct NotifyKeyArgs : public NotifyArgs {
    nsecs_t eventTime;//事件发生的时间
    int32_t deviceId;//设备id
    uint32_t source;//是KeyboardInputMapper初始化时赋值的,
			//其值是INPUT_DEVICE_CLASS_KEYBOARD,INPUT_DEVICE_CLASS_DPAD从,INPUT_DEVICE_CLASS_GAMEPAD的某一个
    uint32_t policyFlags;//对应policyFlags值是策略标志
    int32_t action;//描述按下或者抬起
    int32_t flags;//AKEY_EVENT_FLAG_FROM_SYSTEM,来自系统的,不是注入事件
    int32_t keyCode;//键盘值
    int32_t scanCode;//扫描码
    int32_t metaState;//对应metaState,控制健的按下或抬起
    nsecs_t downTime;//按下时间就等于when
}

4. InputDispatcher.h

4.1结构体

4.1.1 InputTarget

struct InputTarget {
    enum {
        //此标记表示事件正交付给前台应用程序
        FLAG_FOREGROUND = 1 << 0,

        //此标记指示 MotionEvent 位于目标区域内 
        FLAG_WINDOW_IS_OBSCURED = 1 << 1,

        /*此标志表示Motionevent事件正在多个窗口中分割. */
        FLAG_SPLIT = 1 << 2,

        //此标志表示分派给应用程序的指针坐标将被清零,以避免向应用程序泄露信息。
		//这与FLAG_DISPATCH_AS_OUTSIDE一起使用,以防止不共享相同UID的应用程序查看所有触摸. */
        FLAG_ZERO_COORDS = 1 << 3,

        //此标志指示事件应按原样发送。除非要事件发生变化,否则应始终设置此标志
        FLAG_DISPATCH_AS_IS = 1 << 8,

        //此标志指示具有AMOTION_EVENT_ACTION_DOWN的MotionEvent位于此目标区域之外
        FLAG_DISPATCH_AS_OUTSIDE = 1 << 9,

        //此标志表示悬停序列正在给定窗口中开始。
		//事件转换为ACTION_HOVER_ENTER。
        FLAG_DISPATCH_AS_HOVER_ENTER = 1 << 10,

        //此标志表示悬停事件发生在处理先前悬停事件的窗口之外,表示该窗口的当前悬停序列结束。
		//*事件转换为ACTION_HOVER_ENTER*/
        FLAG_DISPATCH_AS_HOVER_EXIT = 1 << 11,

        /* 此标志表示应取消事件。
		//当触摸滑出窗口时,它用于将ACTION_MOVE转换为ACTION_CANCEL。 */
        FLAG_DISPATCH_AS_SLIPPERY_EXIT = 1 << 12,

        /* 此标志表示事件应作为初始dowm进行分发。
		//当触摸滑入新窗口时,它用于将ACTION_MOVE转换为ACTION_DOWN. */
        FLAG_DISPATCH_AS_SLIPPERY_ENTER = 1 << 13,

        /* 所有调度模式的掩码. */
        FLAG_DISPATCH_MASK = FLAG_DISPATCH_AS_IS
                | FLAG_DISPATCH_AS_OUTSIDE
                | FLAG_DISPATCH_AS_HOVER_ENTER
                | FLAG_DISPATCH_AS_HOVER_EXIT
                | FLAG_DISPATCH_AS_SLIPPERY_EXIT
                | FLAG_DISPATCH_AS_SLIPPERY_ENTER,

        //此标志表示MotionEvent的目标部分或全部被其上方的另一个可见窗口遮挡。
		应使用标志AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED传递运动事件。*/
        FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 1 << 14,

    };

    // 目标窗口的通信管道,用于dispatcher和目标窗口进行通信,将事件发送出去
    sp<InputChannel> inputChannel;

    // input targets的标志
    int32_t flags;

    // 屏幕坐标系相对于目标窗口的坐标系偏移量
    // KeyEvents事件忽略
    float xOffset, yOffset;

    // 屏幕坐标系相对于目标窗口的坐标系的缩放系数
    // (KeyEvents事件忽略
    float scaleFactor;

    // The subset of pointer ids to include in motion events dispatched to this input target
    // if FLAG_SPLIT is set.
    BitSet32 pointerIds;
};

 4.1.2 KeyRepeatState

 //按键重复追踪
struct KeyRepeatState {
       KeyEntry* lastKeyEntry; // 上一个按键事件
       nsecs_t nextRepeatTime; 
 } mKeyRepeatState;

 4.1.3 InputDispatcherConfiguration

//InputDispatcher的配置。
//指定修改InputDispatcher的各种选项。
//这里提供的值只是默认值。实际值将来自ViewConfiguration,并在初始化期间传递给InputDispatcher
struct InputDispatcherConfiguration {
    // 重复按键超时
    nsecs_t keyRepeatTimeout;
    // 重复按键按键间延迟
    nsecs_t keyRepeatDelay;
    InputDispatcherConfiguration() :
            keyRepeatTimeout(500 * 1000000LL),
            keyRepeatDelay(50 * 1000000LL) { }
};

 4.1.4 DispatchEntry

// 跟踪将特定事件分派到特定连接的进度.
struct DispatchEntry : Link<DispatchEntry> {
        const uint32_t seq; // 唯一序列号,从不为0

        EventEntry* eventEntry; // 要分发的事件
        int32_t targetFlags;//分发到的目标窗口的flag,如前台窗口等
        float xOffset;
        float yOffset;
        float scaleFactor;//缩放比例
        nsecs_t deliveryTime; // 事件实际交付的时间

        // 当事件排队时,设置resolvedAction和resolvedFlags。
        int32_t resolvedAction;
        int32_t resolvedFlags;

        DispatchEntry(EventEntry* eventEntry,
                int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
        ~DispatchEntry();

        inline bool hasForegroundTarget() const {
            return targetFlags & InputTarget::FLAG_FOREGROUND;
        }

        inline bool isSplit() const {
            return targetFlags & InputTarget::FLAG_SPLIT;
        }

    private:
        static volatile int32_t sNextSeqAtomic;

        static uint32_t nextSeq();
};

4.1.5 Connection

class Connection : public RefBase {
    protected:
        virtual ~Connection();

    public:
        enum Status {
            // 连接状态正常
            STATUS_NORMAL,
            // 发生了不可恢复的通信错误
            STATUS_BROKEN,
            // input channel已注销。
            STATUS_ZOMBIE
        };

        Status status;
        sp<InputChannel> inputChannel; //永不为空
        sp<InputWindowHandle> inputWindowHandle; // 可能为空
        bool monitor;//ims和wms之间的桥梁
        InputPublisher inputPublisher;
        InputState inputState;

        //如果套接字已满,并且在应用程序使用某些输入之前无法发送其他事件,则为True。
        bool inputPublisherBlocked;

        // 事件队列需要发送到Connection
        Queue<DispatchEntry> outboundQueue;

        //已发送到connection但尚未收到应用程序“完成”响应的事件队列。
        Queue<DispatchEntry> waitQueue;

        explicit Connection(const sp<InputChannel>& inputChannel,
                const sp<InputWindowHandle>& inputWindowHandle, bool monitor);

        inline const std::string getInputChannelName() const { return inputChannel->getName(); }

        const std::string getWindowName() const;
        const char* getStatusLabel() const;

        DispatchEntry* findWaitQueueEntry(uint32_t seq);
};

 4.1.6 InjectionState

struct InjectionState {
        mutable int32_t refCount;

        int32_t injectorPid;
        int32_t injectorUid;
        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
        bool injectionIsAsync; // 如果注入没有等待结果,则设置为true
        int32_t pendingForegroundDispatches; // 正在进行的前台分发的数量

        InjectionState(int32_t injectorPid, int32_t injectorUid);
        void release();

    private:
        ~InjectionState();
    };

 4.1.7 InputState

/* 跟踪分发的键和运动事件状态,以便在事件被丢弃时可以合成取消事件。 */
class InputState {
    public:
        InputState();
        ~InputState();

        // 如果没有要取消的状态,则返回true。
        bool isNeutral() const;

        // 如果已知指定的源已接收到停止输入motion事件,则返回true。
        bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;

        //记录刚刚发布的key事件的跟踪信息。如果这个ky事件是要被发送的,则返回true;如果不一致且应跳过,则返回false。
        bool trackKey(const KeyEntry* entry, int32_t action, int32_t flags);

        // 记录刚刚发布的motion事件的跟踪信息。
		//如果这个motion事件是要被发送的,则返回true;如果不一致且应跳过,则返回false。


        bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);

        // 合成当前状态的取消事件并重置跟踪状态。
        void synthesizeCancelationEvents(nsecs_t currentTime,
                Vector<EventEntry*>& outEvents, const CancelationOptions& options);

        // 清楚当前的状态
        void clear();

        // 将输入状态的指针相关部分复制到另一个实例。
        void copyPointerStateTo(InputState& other) const;

        //获取与keycode关联的回退键。
		//如果没有,则返回-1。
		//如果我们只向策略分派未处理的key,则返回AKEYCODE_UNKNOWN。
        int32_t getFallbackKey(int32_t originalKeyCode);

        // 为特定keycode设置回退键.
        void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode);

        // 为特定keycode移除回退键.
        void removeFallbackKey(int32_t originalKeyCode);

        inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const {
            return mFallbackKeys;
        }

    private:
        struct KeyMemento {
            int32_t deviceId;
            uint32_t source;
            int32_t keyCode;
            int32_t scanCode;
            int32_t metaState;
            int32_t flags;
            nsecs_t downTime;
            uint32_t policyFlags;
        };

        struct MotionMemento {
            int32_t deviceId;
            uint32_t source;
            int32_t flags;
            float xPrecision;
            float yPrecision;
            nsecs_t downTime;
            int32_t displayId;
            uint32_t pointerCount;
            PointerProperties pointerProperties[MAX_POINTERS];
            PointerCoords pointerCoords[MAX_POINTERS];
            bool hovering;
            uint32_t policyFlags;

            void setPointers(const MotionEntry* entry);
        };

        Vector<KeyMemento> mKeyMementos;
        Vector<MotionMemento> mMotionMementos;
        KeyedVector<int32_t, int32_t> mFallbackKeys;

        ssize_t findKeyMemento(const KeyEntry* entry) const;
        ssize_t findMotionMemento(const MotionEntry* entry, bool hovering) const;

        void addKeyMemento(const KeyEntry* entry, int32_t flags);
        void addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering);

        static bool shouldCancelKey(const KeyMemento& memento,
                const CancelationOptions& options);
        static bool shouldCancelMotion(const MotionMemento& memento,
                const CancelationOptions& options);
};

4.1.8 CancelationOptions

​/* 指定要取消的事件及其原因. */
struct CancelationOptions {
        enum Mode {
            CANCEL_ALL_EVENTS = 0,//取消所有事件
            CANCEL_POINTER_EVENTS = 1,//取消触摸事件
            CANCEL_NON_POINTER_EVENTS = 2,//取消非触摸事件
            CANCEL_FALLBACK_EVENTS = 3,//取消退回事件
        };

        //用于确定应取消哪些事件的标记。
        Mode mode;

        //描述取消的原因.
        const char* reason;

        // 要取消的key事件的特定keyCode,或-1取消任何键事件
        int32_t keyCode;

        // 要取消事件的设备id, 或-1取消任何设备的事件
        int32_t deviceId;

        CancelationOptions(Mode mode, const char* reason) :
         mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
};




​

4.1.9 PointerCoords

/*
 * Pointer坐标数据。
 */
struct PointerCoords {
    enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128

    // 此结构中存在的轴的位字段。
    uint64_t bits __attribute__((aligned(8)));

    //存储在该结构中的轴的值按轴id 按“位”对结构中存在的每个轴进行排序。
    float values[MAX_AXES];

    inline void clear() {
        BitSet64::clear(bits);
    }

    bool isEmpty() const {
        return BitSet64::isEmpty(bits);
    }

    float getAxisValue(int32_t axis) const;
    status_t setAxisValue(int32_t axis, float value);

    void scale(float scale);
    void applyOffset(float xOffset, float yOffset);

    inline float getX() const {
        return getAxisValue(AMOTION_EVENT_AXIS_X);
    }

    inline float getY() const {
        return getAxisValue(AMOTION_EVENT_AXIS_Y);
    }

#ifdef __ANDROID__
    status_t readFromParcel(Parcel* parcel);
    status_t writeToParcel(Parcel* parcel) const;
#endif

    bool operator==(const PointerCoords& other) const;
    inline bool operator!=(const PointerCoords& other) const {
        return !(*this == other);
    }

    void copyFrom(const PointerCoords& other);

private:
    void tooManyAxes(int axis);
};

4.2 枚举类型

 4.2.1 Motion事件的标志

/** Motion event actions */
enum {
    /** 标识motion code本身的位掩码 ,即所有的motion都有这个位掩码*/
    AMOTION_EVENT_ACTION_MASK = 0xff,

    /**
     * Bits in the action code that represent a pointer index, used with
     * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP.  Shifting
     * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
     * index where the data for the pointer going up or down can be found.
     */
    AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,

    /** A pressed gesture has started, the motion contains the initial starting location. */
    AMOTION_EVENT_ACTION_DOWN = 0,

    /**
     * A pressed gesture has finished, the motion contains the final release location
     * as well as any intermediate points since the last down or move event.
     */
    AMOTION_EVENT_ACTION_UP = 1,

    /**
     * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
     * AMOTION_EVENT_ACTION_UP).  The motion contains the most recent point, as well as
     * any intermediate points since the last down or move event.
     */
    AMOTION_EVENT_ACTION_MOVE = 2,

    /**
     * The current gesture has been aborted.
     * You will not receive any more points in it.  You should treat this as
     * an up event, but not perform any action that you normally would.
     */
    AMOTION_EVENT_ACTION_CANCEL = 3,

    /**
     * A movement has happened outside of the normal bounds of the UI element.
     * This does not provide a full gesture, but only the initial location of the movement/touch.
     */
    AMOTION_EVENT_ACTION_OUTSIDE = 4,

    /**
     * A non-primary pointer has gone down.
     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
     */
    AMOTION_EVENT_ACTION_POINTER_DOWN = 5,

    /**
     * A non-primary pointer has gone up.
     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
     */
    AMOTION_EVENT_ACTION_POINTER_UP = 6,

    /**
     * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
     * The motion contains the most recent point, as well as any intermediate points since
     * the last hover move event.
     */
    AMOTION_EVENT_ACTION_HOVER_MOVE = 7,

    /**
     * The motion event contains relative vertical and/or horizontal scroll offsets.
     * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
     * and AMOTION_EVENT_AXIS_HSCROLL.
     * The pointer may or may not be down when this event is dispatched.
     * This action is always delivered to the winder under the pointer, which
     * may not be the window currently touched.
     */
    AMOTION_EVENT_ACTION_SCROLL = 8,

    /** The pointer is not down but has entered the boundaries of a window or view. */
    AMOTION_EVENT_ACTION_HOVER_ENTER = 9,

    /** The pointer is not down but has exited the boundaries of a window or view. */
    AMOTION_EVENT_ACTION_HOVER_EXIT = 10,

    /* One or more buttons have been pressed. */
    AMOTION_EVENT_ACTION_BUTTON_PRESS = 11,

    /* One or more buttons have been released. */
    AMOTION_EVENT_ACTION_BUTTON_RELEASE = 12,
};

4.2.2 InputTargetWaitCause

// 跟踪ANR超时。
enum InputTargetWaitCause {
    INPUT_TARGET_WAIT_CAUSE_NONE,//anr无原因
    INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,//系统无响应
    INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,//应用无响应
};

4.2.3 输入源标志

enum {
    /** mask */
    AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
    //输入源没有class,由应用程序根据设备类型确定如何处理设备。
    AINPUT_SOURCE_CLASS_NONE = 0x00000000,
    /** 输入设备有按钮或者key,例如:键盘和方向键盘 */
    AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
    /**输入源是与显示器相关联的定点设备。例如:触摸屏,或者鼠标
    AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
    /** 输入源是轨迹球导航设备。 */
    AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
    /** 输入源是与显示器无关的绝对定位设备 */
    AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
    /** 输入原设备是操纵杆 */
    AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010,
};

5.InputTransport.h

文件路径:/frameworks/native/include/input/

5.1 结构体

5.1.1 InputPublisher

class InputPublisher {
public:
    /* 创建与输入通道关联的发布者. */
    explicit InputPublisher(const sp<InputChannel>& channel);

    /* 销毁InputPublisher并释放input channel. */
    ~InputPublisher();

    /* 获取输入通道 */
    inline sp<InputChannel> getChannel() { return mChannel; }

	//将key事件发布到输入通道。
	//成功时返回OK。
	//如果通道已满,则返回WOULD_BLOCK。
	//如果通道的对等端已关闭,则返回DEAD_OBJECT。
	//如果seq为0,则返回BAD_VALUE。
	//其他错误可能表明通道已断开。
    status_t publishKeyEvent(
            uint32_t seq,
            int32_t deviceId,
            int32_t source,
            int32_t action,
            int32_t flags,
            int32_t keyCode,
            int32_t scanCode,
            int32_t metaState,
            int32_t repeatCount,
            nsecs_t downTime,
            nsecs_t eventTime);

	//将motion事件发布到输入通道。
	//成功时返回OK。
	//如果通道已满,则返回WOULD_BLOCK。
	//如果通道的对等端已关闭,则返回DEAD_OBJECT。
	//如果seq为0或pointerCount小于1或大于MAX_POINTERS,则返回BAD_VALUE。
	//其他错误可能表明通道已断开。
    status_t publishMotionEvent(
            uint32_t seq,
            int32_t deviceId,
            int32_t source,
            int32_t displayId,
            int32_t action,
            int32_t actionButton,
            int32_t flags,
            int32_t edgeFlags,
            int32_t metaState,
            int32_t buttonState,
            float xOffset,
            float yOffset,
            float xPrecision,
            float yPrecision,
            nsecs_t downTime,
            nsecs_t eventTime,
            uint32_t pointerCount,
            const PointerProperties* pointerProperties,
            const PointerCoords* pointerCoords);

	//接收consumer发出的完成信号,作为对原始调度信号的回复。
	//如果接收到信号,则返回消息序列号,以及消费者是否处理了消息。
	//除非操作失败,否则返回的序列号永远不会为0。
	//成功时返回OK。
	//如果没有信号,则返回WOULD_BLOCK。
	//如果通道的对等端已关闭,则返回DEAD_OBJECT。
	//其他错误可能表明通道已断开。
    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);

private:
    sp<InputChannel> mChannel;
};

5.1.2 InputConsumer

class InputConsumer {
public:
    //创建与输入通道关联的InputConsumer
    explicit InputConsumer(const sp<InputChannel>& channel);

    /* Destroys the consumer and releases its input channel. */
    ~InputConsumer();

    /* 获取与之相关的input channel. */
    inline sp<InputChannel> getChannel() { return mChannel; }


	//消费一个从inputchannel中的input event,并将其内容复制到一个特定工厂创建的InputEvent对象中
	
	//尽可能尝试将一系列move event组合成更大的批次。
     *
     * If consumeBatches is false, then defers consuming pending batched events if it
     * is possible for additional samples to be added to them later.  Call hasPendingBatch()
     * to determine whether a pending batch is available to be consumed.
	//如果consumeBatches为false,那么如果以后可以向其添加其他事件,则推迟消费未处理的一批事件。
	//调用hasPendingBatch()确定是否待处理的批次可供消耗。
	//如果consumeBatches为true,则事件仍然是批处理的,但是一旦输入通道耗尽,它们就会立即被消耗。

    //frameTime参数指定当前显示帧在CLOCK_MONOTONIC时基中开始渲染的时间,如果未知,则为-1。
    //除非操作失败,否则返回的序列号永远不会为0。
    //成功时返回OK。
	//如果不存在事件,则返回WOULD_BLOCK。
	//如果通道的对等端已关闭,则返回DEAD_OBJECT。
	//如果无法创建事件,则返回NO_MEMORY。
	//其他错误可能表明通道已断开。
    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId);

    //向publisher发送完成信号,通知其具有指定序列号的消息已完成处理,以及该消息是否已由使用者处理。
	//成功时返回OK。
	//如果seq为0,则返回BAD_VALUE。
	//其他错误可能表明通道已断开。
    status_t sendFinishedSignal(uint32_t seq, bool handled);

	//如果有延迟事件等待,则返回true。
	//应在调用consume()后调用,以确定消费者是否有要处理的延迟事件。
	//延迟事件有些特殊,因为它们已经从输入通道中删除。如果输入通道变空,客户端可能需要做额外的工作,
	//以确保它处理延迟的事件,尽管输入通道的文件描述符不可读。

	//一种方法是简单地在循环中调用consume(),直到它返回WOULD_BLOCK。这保证将处理所有延迟事件。
	//或者,调用者可以调用hasDeferredEvent()来确定是否有延迟事件等待,然后确保其事件循环至少再唤醒一次以消耗延迟事件。
    bool hasDeferredEvent() const;

    /* 如果存在挂起的批,则返回true。
     *
     * Should be called after calling consume() with consumeBatches == false to determine
     * whether consume() should be called again later on with consumeBatches == true.
     */
    bool hasPendingBatch() const;

private:
    //如果启用触摸重采样,则为True。
    const bool mResampleTouch;

    //input channel.
    sp<InputChannel> mChannel;

    //当前的input message.
    InputMessage mMsg;

    //如果mMsg包含一个有效的是从从上一次调用给consume的但是被延迟了的输入消息,是仍然需要处理。
    bool mMsgDeferred;

    //每个设备和源的成批的motion events。
    struct Batch {
        Vector<InputMessage> samples;
    };
    Vector<Batch> mBatches;

    // 每个设备和源的触摸状态,仅针对类指针的源.
    struct History {
        nsecs_t eventTime;
        BitSet32 idBits;
        int32_t idToIndex[MAX_POINTER_ID + 1];
        PointerCoords pointers[MAX_POINTERS];

        void initializeFrom(const InputMessage& msg) {
            eventTime = msg.body.motion.eventTime;
            idBits.clear();
            for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
                uint32_t id = msg.body.motion.pointers[i].properties.id;
                idBits.markBit(id);
                idToIndex[id] = i;
                pointers[i].copyFrom(msg.body.motion.pointers[i].coords);
            }
        }

        void initializeFrom(const History& other) {
            eventTime = other.eventTime;
            idBits = other.idBits; // temporary copy
            for (size_t i = 0; i < other.idBits.count(); i++) {
                uint32_t id = idBits.clearFirstMarkedBit();
                int32_t index = other.idToIndex[id];
                idToIndex[id] = index;
                pointers[index].copyFrom(other.pointers[index]);
            }
            idBits = other.idBits; // final copy
        }

        const PointerCoords& getPointerById(uint32_t id) const {
            return pointers[idToIndex[id]];
        }

        bool hasPointerId(uint32_t id) const {
            return idBits.hasBit(id);
        }
    };
    struct TouchState {
        int32_t deviceId;
        int32_t source;
        size_t historyCurrent;
        size_t historySize;
        History history[2];
        History lastResample;

        void initialize(int32_t deviceId, int32_t source) {
            this->deviceId = deviceId;
            this->source = source;
            historyCurrent = 0;
            historySize = 0;
            lastResample.eventTime = 0;
            lastResample.idBits.clear();
        }

        void addHistory(const InputMessage& msg) {
            historyCurrent ^= 1;
            if (historySize < 2) {
                historySize += 1;
            }
            history[historyCurrent].initializeFrom(msg);
        }

        const History* getHistory(size_t index) const {
            return &history[(historyCurrent + index) & 1];
        }

        bool recentCoordinatesAreIdentical(uint32_t id) const {
            // Return true if the two most recently received "raw" coordinates are identical
            if (historySize < 2) {
                return false;
            }
            if (!getHistory(0)->hasPointerId(id) || !getHistory(1)->hasPointerId(id)) {
                return false;
            }
            float currentX = getHistory(0)->getPointerById(id).getX();
            float currentY = getHistory(0)->getPointerById(id).getY();
            float previousX = getHistory(1)->getPointerById(id).getX();
            float previousY = getHistory(1)->getPointerById(id).getY();
            if (currentX == previousX && currentY == previousY) {
                return true;
            }
            return false;
        }
    };
    Vector<TouchState> mTouchStates;

    //批处理序列号链。当多条输入消息合并到一个批中时,我们在这里附加一条记录,将批中的最后一个序列号与前一个序列相关联。
	//当发送完成的信号时,我们遍历该链,以单独完成作为批处理一部分的所有输入消息。
    struct SeqChain {
        uint32_t seq;   //batched input message的序列号
        uint32_t chain; //前一批input message的序列号
    };
    Vector<SeqChain> mSeqChains;

    status_t consumeBatch(InputEventFactoryInterface* factory,
            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId);
    status_t consumeSamples(InputEventFactoryInterface* factory,
            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent,
            int32_t* displayId);

    void updateTouchState(InputMessage& msg);
    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
            const InputMessage *next);

    ssize_t findBatch(int32_t deviceId, int32_t source) const;
    ssize_t findTouchState(int32_t deviceId, int32_t source) const;

    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);

    static void rewriteMessage(TouchState& state, InputMessage& msg);
    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
    static void addSample(MotionEvent* event, const InputMessage* msg);
    static bool canAddSample(const Batch& batch, const InputMessage* msg);
    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
    static bool shouldResampleTool(int32_t toolType);

    static bool isTouchResamplingEnabled();
};

5.1.3 InputMessage

struct InputMessage {
    enum {
        TYPE_KEY = 1,//按键事件
        TYPE_MOTION = 2,//motion事件
        TYPE_FINISHED = 3,//表示发送完成事件
    };

    struct Header {
        uint32_t type;
        // We don't need this field in order to align the body below but we
        // leave it here because InputMessage::size() and other functions
        // compute the size of this structure as sizeof(Header) + sizeof(Body).
        uint32_t padding;
    } header;

    // Body *must* be 8 byte aligned.
    union Body {
        struct Key {
            uint32_t seq;
            uint32_t empty1;
            nsecs_t eventTime __attribute__((aligned(8)));
            int32_t deviceId;
            int32_t source;
            int32_t displayId;
            int32_t action;
            int32_t flags;
            int32_t keyCode;
            int32_t scanCode;
            int32_t metaState;
            int32_t repeatCount;
            uint32_t empty2;
            nsecs_t downTime __attribute__((aligned(8)));

            inline size_t size() const {
                return sizeof(Key);
            }
        } key;

        struct Motion {
            uint32_t seq;
            uint32_t empty1;
            nsecs_t eventTime __attribute__((aligned(8)));
            int32_t deviceId;
            int32_t source;
            int32_t displayId;
            int32_t action;
            int32_t actionButton;
            int32_t flags;
            int32_t metaState;
            int32_t buttonState;
            int32_t edgeFlags;
            uint32_t empty2;
            nsecs_t downTime __attribute__((aligned(8)));
            float xOffset;
            float yOffset;
            float xPrecision;
            float yPrecision;
            uint32_t pointerCount;
            uint32_t empty3;
            // Note that PointerCoords requires 8 byte alignment.
            struct Pointer {
                PointerProperties properties;
                PointerCoords coords;
            } pointers[MAX_POINTERS];

            int32_t getActionId() const {
                uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
                        >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
                return pointers[index].properties.id;
            }

            inline size_t size() const {
                return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
                        + sizeof(Pointer) * pointerCount;
            }
        } motion;

        struct Finished {
            uint32_t seq;
            bool handled;

            inline size_t size() const {
                return sizeof(Finished);
            }
        } finished;
    } __attribute__((aligned(8))) body;

    bool isValid(size_t actualSize) const;
    size_t size() const;
    void getSanitizedCopy(InputMessage* msg) const;
};

 6.com_android_server_input_InputManagerService.cpp

/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

6.1 结构体

6.1.1 Locked

struct Locked {
        // 显示大小信息
        DisplayViewport internalViewport;
        DisplayViewport externalViewport;
        Vector<DisplayViewport> virtualViewports;

        // 系统UI可见性。
        int32_t systemUiVisibility;

        // 指针速度
        int32_t pointerSpeed;

        // True if pointer gestures are enabled.
        bool pointerGesturesEnabled;

        // 显示触摸功能启用/禁用。
        bool showTouches;

        // Pointer capture feature enable/disable.
        bool pointerCapture;

        // Sprite controller singleton, created on first use.
        sp<SpriteController> spriteController;

        // Pointer controller singleton, created and destroyed as needed.
        wp<PointerController> pointerController;//指针移动的控制器集合

        // 要禁用的输入设备
        SortedVector<int32_t> disabledInputDevices;
} mLocked;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么认识和应用Redis内部数据结构?no.22

Redis 内部数据结构 RdeisDb Redis 中所有数据都保存在 DB 中&#xff0c;一个 Redis 默认最多支持 16 个 DB。Redis 中的每个 DB 都对应一个 redisDb 结构&#xff0c;即每个 Redis 实例&#xff0c;默认有 16 个 redisDb。用户访问时&#xff0c;默认使用的是 0 号 DB&#…

NLP(18)--大模型发展(2)

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 LLM的结构变化&#xff1a; Muti-head 共享&#xff1a; Q继续切割为muti-head,但是K,V少切&#xff0c;比如切为2个&#xff0c;然后复制到n个muti-head减少参数量&#xff0c;加速训练 attention结构改动&#xff1a; s…

数据安全保护的权益有什么?

针对个人主体&#xff0c;数据需要保护的权益有&#xff1a; 个人的隐私安全、社交安全、财产安全、支付安全、各类权利安全、生命安全、声誉安全 这些权益在物理世界中也基本都是存在的&#xff0c;只不过在数字世界中进行了映射或者重构。 针对企业的主体&#xff0c;需要保…

非常简单的副业兼职,知乎问答。每天半小时,收益240+

近期平台陆续为我带来了约240元的收入。实现这一目标并不需要复杂的方法或技巧&#xff0c;甚至可以说是零粉丝、零门槛。只需每天抽出半小时进行复制粘贴操作即可。在此&#xff0c;我希望能为那些缺乏基础的小伙伴们提供一些微不足道的经验和启示。 周周近财&#xff1a;让网…

(六)DockerCompose安装与配置

DockerCompose简介 Compose 项目是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的快速编排。使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中&#xff0c;经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现…

HQL面试题练习 —— 互相关注

目录 1 题目2 建表语句3 题解 1 题目 现有用户关注者列表记录表 t_user_follower&#xff0c;有两个字段&#xff0c;用户ID&#xff08;user_id&#xff09;&#xff0c;关注者列表&#xff08;follower_ids)&#xff0c;关注者列表中是关注用户的用户ID&#xff0c;数据样例如…

JavaEE-文件IO1

文章目录 一、什么是文件IO?1.1 IO1.2 文件1.2.1 路径1.2.2 文件分类 二、使用Java针对文件系统进行操作 一、什么是文件IO? 1.1 IO IO分别代表Input和Output即输入和输出。比如我的电脑可以从网络上下载文件&#xff0c;也可以通过网络上传文件或者我把我的内存中的数据保…

第 8 章 机器人实体导航实现01_准备工作(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 9.3.1 导航实现01_准备工作 1.1分布式架构 分布式架构搭建完毕且能正常运行&#xff0c;在PC端可以远程登陆…

性能测试——性能问题分析步骤

前言 性能测试大致分以下几个步骤&#xff1a; 需求分析 脚本准备 测试执行 结果整理 问题分析 今天要说的是最后一个步骤——“问题分析”&#xff1b; 需求描述 有一个服务&#xff0c;启动时会加载一个1G的词表文件到内存&#xff0c;请求来了之后&#xff0c;会把…

【前端】使用 Canvas 实现贪吃蛇小游戏

使用 Canvas 实现贪吃蛇小游戏 在这篇博客中&#xff0c;我们将介绍如何使用 HTML5 Canvas 和 JavaScript 实现一个简单的贪吃蛇&#xff08;Snake&#xff09;小游戏。这个项目是一个基础的游戏开发练习&#xff0c;它可以帮助你理解如何在 Canvas 上绘图、如何处理用户输入以…

【Spring security】【pig】Note03-pig token令牌解析器过程

&#x1f338;&#x1f338; pig token令牌解析器过程 &#x1f338;&#x1f338; pig后端源码 一、解析请求中的令牌值。 二、验证令牌 内省并验证给定的令牌&#xff0c;返回其属性。返回映射表示令牌有效。 /*** author lengleng* date 2019/2/1 扩展用户信息*/ publi…

重新安装vmware与再次编译u-boot

一、使用环境&#xff1a; 使用vmware 16pro安装 ubuntu18.04桌面版 二、遇到的问题与解决&#xff1a; 1&#xff09;、无法连网&#xff1a; 保持nat模式&#xff0c;移除再添加。 2&#xff09;、git配置私钥&#xff1a; 如果是拉取自己的仓库&#xff0c;请查看此步&am…

电路笔记 :元器件焊接相关 酒精灯松香浴加热取芯片

记录一下只使用松香和小火源加热&#xff08;如酒精灯、小蜡烛&#xff09;从电路板中取芯片。 过程 多放松香 让松香淹没芯片尽量均匀加热&#xff0c;等芯片旁边的松香开始从芯片里冒细小的“泡泡”&#xff0c;就差不多了 注&#xff1a;这种方法也可以用于焊接&#xff0…

232COM串口通讯读写NFC卡C#示例源码

本示例使用的发卡器&#xff1a;RS232串口RFID NFC IC卡读写器可二次开发编程发卡器USB转COM-淘宝网 (taobao.com) using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Syste…

【技术实操】中标麒麟高级服务器操作系统实例分享,rsync数据同步配置方案

1.rsync介绍 rsync是一款开源的、快速的、多功能的、可实现全量及增量的本地或远程数据同步备份工具。 在守护进程模式&#xff08;daemon mode&#xff09;下&#xff0c;rsync默认监听TCP端口873&#xff0c;以原生rsync传输协议或者通过远程shell如RSH或者SSH提供文件。SS…

App Inventor 2 如何接入ChatGPT:国内访问OpenAI的最佳方式

如何接入OpenAI 由于国内无法访问OpenAI&#xff0c;KX上网可选大陆及香港&#xff08;被屏蔽&#xff09;以外才行。因此对于大多数人来说&#xff0c;想体验或使用ChatGPT就不太便利&#xff0c;不过App Inventor 2 为我们提供了相对便利的一种方式&#xff0c;即“试验性质…

快速搭建SpringMvc项目

一、什么是springMvc 1、介绍 Spring Web MVC是基于Servlet API构建的原始Web框架&#xff0c;从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称&#xff08; spring-webmvc &#xff09;&#xff0c;但它通常被称为“Spring MVC”。 在控制…

MVS net笔记和理解

文章目录 传统的方法有什么缺陷吗&#xff1f;MVSnet深度的预估 传统的方法有什么缺陷吗&#xff1f; 传统的mvs算法它对图像的光照要求相对较高&#xff0c;但是在实际中要保证照片的光照效果很好是很难的。所以传统算法对镜面反射&#xff0c;白墙这种的重建效果就比较差。 …

京准电子、NTP网络时间服务器工作原理及应用领域分析

京准电子、NTP网络时间服务器工作原理及应用领域分析 京准电子、NTP网络时间服务器工作原理及应用领域分析 Network Time Protocol&#xff08;NTP&#xff09;是一种用于在计算机网络中同步时钟的协议。它旨在确保在网络中的各个设备之间维持准确的时间。NTP的设计目标是允许…

qmt量化交易策略小白学习笔记第10期【qmt编程之获取股票订单流数据--内置Python】

qmt编程之获取股票订单流数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;需免费开通量化回测与咨询实盘权限&#xff0c;可以和博主联系&#xff01; 获取股票订单流…