系列文章目录
目录
1.2.1 InputDeviceConfigurationFileType
2.1.2 InputReaderConfiguration
2.1.4 VelocityControlParameters
4.1.3 InputDispatcherConfiguration
6.com_android_server_input_InputManagerService.cpp
简介
由于后续篇幅如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;