开局叠甲,可能理解有误,请大佬们斧正。
- Android Framework-Input-1 基础梳理
- Android Framework-Input-2 构建和启动
- Android Framework-Input-3 数据处理
- Android Framework-Input-4 IQ到OQ
- Android Framework-Input-5 分发事件
- Android Framework-Input-6 事件分发到View
- Android Framework-Input-7 事件的移除
- Android Framework-Input-8 ANR相关
Looper 和EventHub
- EventHub
static const char* DEVICE_PATH = "/dev/input";
EventHub::EventHub(void)
: mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
mNextDeviceId(1),
mControllerNumbers(),
mNeedToSendFinishedDeviceScan(false),
mNeedToReopenDevices(false),
mNeedToScanDevices(true),
mPendingEventCount(0),
mPendingEventIndex(0),
mPendingINotify(false) {
ensureProcessCanBlockSuspend();
mEpollFd = epoll_create1(EPOLL_CLOEXEC);
//初始化
mINotifyFd = inotify_init();
//对/dev/input 进行监听 创建和删除都会触发监听
mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
struct epoll_event eventItem = {};
//可读时间监听
eventItem.events = EPOLLIN | EPOLLWAKEUP;
eventItem.data.fd = mINotifyFd;
int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
int wakeFds[2];
//管道创建
result = pipe(wakeFds);
//读写的句柄
mWakeReadPipeFd = wakeFds[0];
mWakeWritePipeFd = wakeFds[1];
//设置非阻塞
result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
//赋值data
eventItem.data.fd = mWakeReadPipeFd;
//监听
result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
}
// 简单理解 eventHub对 input 目录进行了监听 ,有添加或者删除 都会进行通知 notify
//https://blog.csdn.net/feelabclihu/article/details/123013494
struct RawEvent {
nsecs_t when;
nsecs_t readTime;
int32_t deviceId;
int32_t type;
int32_t code;
int32_t value;
};
- Looper
Looper::Looper(bool allowNonCallbacks)
: mAllowNonCallbacks(allowNonCallbacks),
mSendingMessage(false),
mPolling(false),
mEpollRebuildRequired(false),
mNextRequestSeq(0),
mResponseIndex(0),
mNextMessageUptime(LLONG_MAX) {
mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
LOG_ALWAYS_FATAL_IF(mWakeEventFd.get() < 0, "Could not make wake event fd: %s", strerror(errno));
AutoMutex _l(mLock);
rebuildEpollLocked();
}
void Looper::rebuildEpollLocked() {
if (mEpollFd >= 0) {
mEpollFd.reset();
}
mEpollFd.reset(epoll_create1(EPOLL_CLOEXEC));
struct epoll_event eventItem;
//初始化 eventItem
memset(& eventItem, 0, sizeof(epoll_event));
eventItem.events = EPOLLIN;
eventItem.data.fd = mWakeEventFd.get();
//对mWakeEventFd 监听 监听事件是 可读写
int result = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mWakeEventFd.get(), &eventItem);
//对mRequests 遍历监听 默认是1 就一个屏幕
for (size_t i = 0; i < mRequests.size(); i++) {
const Request& request = mRequests.valueAt(i);
struct epoll_event eventItem;
request.initEventItem(&eventItem);
// 添加一个监听对象 监听的类型是 eventItem中的类型
int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, request.fd, &eventItem);
}
}
//简单理解 Looper 内部也有对mEpollFd 的监听 对关心的
在调用start()之后,
InputReader调用了loopOnce()
//native/services/inputflinger/reader/InputReader.cpp
void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
{
//省略
//1.1 mEventHub获取数据 static const int EVENT_BUFFER_SIZE = 256; 也就说一次最多搞256个消息
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{
std::scoped_lock _l(mLock);
mReaderIsAliveCondition.notify_all();
//拿到了event 事件 就去处理
if (count) {
//1.2 处理数据
processEventsLocked(mEventBuffer, count);
}
if (oldGeneration != mGeneration) {
inputDevicesChanged = true;
inputDevices = getInputDevicesLocked();
}
}
if (inputDevicesChanged) {
mPolicy->notifyInputDevicesChanged(inputDevices);
}
//将事件刷进去, 这里会调用到 NotifyMotionArgs::notify 因为我们暂时看的是这个类型 然后回调 listener->notifyMotion(this); 进入dispatcher 的 notifyMotion 进入iQ 然后才会触发wake 触发dispatonce 进入oq的循环
mQueuedListener->flush();
}
1.1 EventHub->getEvents
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
std::scoped_lock _l(mLock);
struct input_event readBuffer[bufferSize];
RawEvent* event = buffer;
size_t capacity = bufferSize;
bool awoken = false;
for (;;) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
//扫描/dev/input 路径下 并对文件夹打开 对里面的文件 进行ioctrl 调用到驱动层 获取对应的属性
//可以理解为扫描 外面的设备是什么屏幕啊 支持不支持触摸啊啥的 最后调用registerDeviceForEpollLocked 注册进去,
scanDevicesLocked();
mNeedToSendFinishedDeviceScan = true;
}
//遍历已经打开的节点, 并串联起来
while (!mOpeningDevices.empty()) {
std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
mOpeningDevices.pop_back();
event->when = now;
event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
event->type = DEVICE_ADDED;
event += 1;
// Try to find a matching video device by comparing device names
for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
it++) {
std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
if (tryAddVideoDeviceLocked(*device, videoDevice)) {
// videoDevice was transferred to 'device'
it = mUnattachedVideoDevices.erase(it);
break;
}
}
auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
mNeedToSendFinishedDeviceScan = true;
if (--capacity == 0) {
break;
}
}
//第一次扫描完消息
if (mNeedToSendFinishedDeviceScan) {
mNeedToSendFinishedDeviceScan = false;
event->when = now;
event->type = FINISHED_DEVICE_SCAN;
event += 1;
if (--capacity == 0) {
break;
}
}
// Grab the next input event.
bool deviceChanged = false;
//第一次扫描时候没有消息,指导后面有触摸消息才会进入这里,这里是会由下面epoll监听消息触发
while (mPendingEventIndex < mPendingEventCount) {
const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
if (eventItem.data.fd == mINotifyFd) {
if (eventItem.events & EPOLLIN) {
mPendingINotify = true;
} else {
ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
}
continue;
}
//省略
Device* device = getDeviceByFdLocked(eventItem.data.fd);
continue;
}
if (eventItem.events & EPOLLIN) {
int32_t readSize =
read(device->fd, readBuffer, sizeof(struct input_event) * capacity);
if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
deviceChanged = true;
closeDeviceLocked(*device);
} else if (readSize < 0) {
//省略
} else if ((readSize % sizeof(struct input_event)) != 0) {
//省略
} else {
//省略
int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
//获取真实读取到的inputevent数据真实个数
size_t count = size_t(readSize) / sizeof(struct input_event);
//构造出对应的event
for (size_t i = 0; i < count; i++) {
struct input_event& iev = readBuffer[i];
event->when = processEventTimestamp(iev);
event->readTime = systemTime(SYSTEM_TIME_MONOTONIC);
event->deviceId = deviceId;
event->type = iev.type;
event->code = iev.code;
event->value = iev.value;
event += 1;
capacity -= 1;
}
if (capacity == 0) {
mPendingEventIndex -= 1;
break;
}
}
} else if (eventItem.events & EPOLLHUP) {
deviceChanged = true;
closeDeviceLocked(*device);
} //省略
}
// 第一次扫描就会进入这里进行返回
if (event != buffer || awoken) {
break;
}
mPendingEventIndex = 0;
mLock.unlock(); // release lock before poll
//epoll在等待消息产生,产生消息EventItem都会放到mPendingEventItems中
int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
mLock.lock(); // reacquire lock after poll
if (pollResult == 0) {
mPendingEventCount = 0;
break;
}
}
return event - buffer;
}
总结:
- 获取设备
device各个信息,及监听设备变化 - 监听各个设备产生数据,并转换变成元数据
RawEvent - 最后会把一个个的
RawEvent放入到传递进来的event,这个链表里面即外面传进来的最大的256数组
1.2 processEventsLocked()
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
//首先判断type类型,如果已经开始触摸,那么这里type值肯定会小于FIRST_SYNTHETIC_EVENT
//这里值是 0x10000000 第一次的时候没有添加 那肯定是走else 直到上面的scan 扫描完才是FIRST_SYNTHETIC_EVENT =Add 只要屏幕已经添加完成 那就走这里了
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
int32_t deviceId = rawEvent->deviceId;
while (batchSize < count) {
//判断是否有其他消息,或者设备都换了,存在则退出这次数据的系列
if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
rawEvent[batchSize].deviceId != deviceId) {
break;
}
//一个触摸事件是由若干个RawEvent组成,比如触摸滑动,他有abs,syn等类型
batchSize += 1;
}
//把一个系列事件完成后进行processEvents进行处理 这里相当于将一整个事件的event 传递处理
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
//以下几种都是对设备相关移除添加进行操作的 第一次会走这里 这里主要是对那些数据转bean 做处理
//刚扫描完是add 所以走Add
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
addDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED:
removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
handleConfigurationChangedLocked(rawEvent->when);
break;
default:
ALOG_ASSERT(false); // can't happen
break;
}
}
count -= batchSize;
rawEvent += batchSize;
}
}
总结:
- 这里会将一个系列的消息进行合并后处理。 这里的系列,比如都是触摸屏的,可能有键盘的,但是会放在其他类型里。 属于比较复杂的逻辑 ,不强求, 理解万岁。
addDeviceLocked()
void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
//省略
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
//构建了InputDevice
std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
device->configure(when, &mConfig, 0);
device->reset(when);
//省略
mDevices.emplace(eventHubId, device);
const auto mapIt = mDeviceToEventHubIdsMap.find(device);
if (mapIt == mDeviceToEventHubIdsMap.end()) {
std::vector<int32_t> ids = {eventHubId};
mDeviceToEventHubIdsMap.emplace(device, ids);
} else {
mapIt->second.push_back(eventHubId);
}
bumpGenerationLocked();
}
总结:好像就搞了个解析器 ,我也没理解作用。
processEventsForDeviceLocked()
//第一个逻辑 就是把一个事件 直接转圈跑完 除非 deviceid 不一样 那就是别人的事件了 归到一起处理 搞到一个列表里 弄成一个事件集
void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
size_t count) {
//看看是不是包含该id ,比如这个屏幕还在线么
auto deviceIt = mDevices.find(eventHubId);
if (deviceIt == mDevices.end()) {
return;
}
//把inputDeice 拿出来,这里是个pair 不同的device 有不同的InputDevice
//他们的加入是在scan 那里加入的 比如 一个触摸屏对一个inputDevice
std::shared_ptr<InputDevice>& device = deviceIt->second;
if (device->isIgnored()) {
// ALOGD("Discarding event for ignored deviceId %d.", deviceId);
return;
}
//调用 process
device->process(rawEvents, count);//InputDevice.process
}
//native/services/inputflinger/reader/InputDevice.cpp
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper)
mapper.process(rawEvent);//MultiTouchInputMapper->process 多指触摸屏 可能有多个 但是 我们现在只有一个
});
}
}
//native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
TouchInputMapper::process(rawEvent);//先走父类的 会处理开始和已经完成
mMultiTouchMotionAccumulator.process(rawEvent);//时间的处理
}
void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_ABS) {//首先是不是ABS类型 如果是SYN类型 就得找父类了
bool newSlot = false;//是不是新的触点
if (mUsingSlotsProtocol) {//是否是B协议 一般这里都是true
if (rawEvent->code == ABS_MT_SLOT) {//新的触点 ABS_MT_SLOT就代表新的触点
mCurrentSlot = rawEvent->value;
newSlot = true;//标识为新的触点
}
} else if (mCurrentSlot < 0) {
mCurrentSlot = 0;
}
if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {//mSlotCount是16 触摸手指的最大数量
#if DEBUG_POINTERS
if (newSlot) {
//省略
}
#endif
} else {
Slot* slot = &mSlots[mCurrentSlot];
if (!mUsingSlotsProtocol) {
slot->mInUse = true;
}
switch (rawEvent->code) {//访问code的值 如果是ABS_MT_SLOT 就直接结束了相当于我就标注下 第一次触摸了
case ABS_MT_POSITION_X://x 和y的都比较好理解
slot->mAbsMTPositionX = rawEvent->value;
warnIfNotInUse(*rawEvent, *slot);
break;
case ABS_MT_POSITION_Y:
slot->mAbsMTPositionY = rawEvent->value;
warnIfNotInUse(*rawEvent, *slot);
break;
case ABS_MT_TOUCH_MAJOR:
slot->mAbsMTTouchMajor = rawEvent->value;
break;
case ABS_MT_TOUCH_MINOR:
slot->mAbsMTTouchMinor = rawEvent->value;
slot->mHaveAbsMTTouchMinor = true;
break;
case ABS_MT_WIDTH_MAJOR:
slot->mAbsMTWidthMajor = rawEvent->value;
break;
case ABS_MT_WIDTH_MINOR:
slot->mAbsMTWidthMinor = rawEvent->value;
slot->mHaveAbsMTWidthMinor = true;
break;
case ABS_MT_ORIENTATION:
slot->mAbsMTOrientation = rawEvent->value;
break;
case ABS_MT_TRACKING_ID://如果value小于0 则代表松开了
if (mUsingSlotsProtocol && rawEvent->value < 0) {
slot->mInUse = false;//标识为不使用了
} else {
slot->mInUse = true;//第一个手指头的id
slot->mAbsMTTrackingId = rawEvent->value;
}
break;
case ABS_MT_PRESSURE:
slot->mAbsMTPressure = rawEvent->value;
break;
case ABS_MT_DISTANCE:
slot->mAbsMTDistance = rawEvent->value;
break;
case ABS_MT_TOOL_TYPE:
slot->mAbsMTToolType = rawEvent->value;
slot->mHaveAbsMTToolType = true;
break;
}
}
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
// MultiTouch Sync: The driver has returned all data for *one* of the pointers.
mCurrentSlot += 1;
}
}
//处理最近的 ABS类型手指事件 和其他相关事件如果遇到EV_SYN 教给父类去处理
//native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
void TouchInputMapper::process(const RawEvent* rawEvent) {
mCursorButtonAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
// 处理事件的完成 SYN_REPORT ABS 打头的是其他类型的数据
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
sync(rawEvent->when, rawEvent->readTime);
}
}
sync
//native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
mRawStatesPending.emplace_back();
RawState& next = mRawStatesPending.back();
next.clear();
next.when = when;
next.readTime = readTime;
next.buttonState =
mTouchButtonAccumulator.getButtonState() | mCursorButtonAccumulator.getButtonState();
next.rawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
next.rawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
mCursorScrollAccumulator.finishSync();
//MultiTouchInputMapper::syncTouch()
syncTouch(when, &next);
const RawState& last =
mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1];
// Assign pointer ids.
if (!mHavePointerIds) {
assignPointerIds(last, next);
}
//省略
processRawTouches(false /*timeout*/);
}
syncTouch(数据的处理)
//native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
void MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
size_t outCount = 0;
BitSet32 newPointerIdBits;
mHavePointerIds = true;
//一个个遍历手指头 最多16个
for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
const MultiTouchMotionAccumulator::Slot* inSlot =
mMultiTouchMotionAccumulator.getSlot(inIndex);
if (!inSlot->isInUse()) {//查询状态 不是在使用 直接抛弃 查询下一个
continue;
}
if (inSlot->getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM) {
std::optional<int32_t> id = getActiveBitId(*inSlot);
if (id) {
outState->rawPointerData.canceledIdBits.markBit(id.value());
}
continue;
}
if (outCount >= MAX_POINTERS) {
//过多手指 16
break; //
}
//构建一个触点 然后填充数据
RawPointerData::Pointer& outPointer = outState->rawPointerData.pointers[outCount];
outPointer.x = inSlot->getX();
outPointer.y = inSlot->getY();
outPointer.pressure = inSlot->getPressure();
outPointer.touchMajor = inSlot->getTouchMajor();
outPointer.touchMinor = inSlot->getTouchMinor();
outPointer.toolMajor = inSlot->getToolMajor();
outPointer.toolMinor = inSlot->getToolMinor();
outPointer.orientation = inSlot->getOrientation();
outPointer.distance = inSlot->getDistance();
outPointer.tiltX = 0;
outPointer.tiltY = 0;
outPointer.toolType = inSlot->getToolType();
if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
outPointer.toolType = mTouchButtonAccumulator.getToolType();
if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
}
}
bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE &&
(mTouchButtonAccumulator.isHovering() ||
(mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
outPointer.isHovering = isHovering;
if (mHavePointerIds) {
//将触摸id 赋值过去
int32_t trackingId = inSlot->getTrackingId();
int32_t id = -1;
if (trackingId >= 0) {//如果是-1 就进不来了 证明没id 就是松手了
for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty();) {
uint32_t n = idBits.clearFirstMarkedBit();
if (mPointerTrackingIdMap[n] == trackingId) {
id = n;
}
}
if (id < 0 && !mPointerIdBits.isFull()) {
id = mPointerIdBits.markFirstUnmarkedBit();
mPointerTrackingIdMap[id] = trackingId;
}
}
if (id < 0) {
mHavePointerIds = false;
outState->rawPointerData.clearIdBits();
newPointerIdBits.clear();
} else {
outPointer.id = id;
outState->rawPointerData.idToIndex[id] = outCount;
outState->rawPointerData.markIdBit(id, isHovering);
newPointerIdBits.markBit(id);
}
}
outCount += 1;
}
outState->rawPointerData.pointerCount = outCount;
mPointerIdBits = newPointerIdBits;
mMultiTouchMotionAccumulator.finishSync();
}
这里涉及BitSet32, 这块代码怎么理解。我这是个人理解,不一定对。
比如默认是
0000 0000 0000 0000。
第一次按下
就变成了
1000 0000 0000 0000 ,这里的id[0]就赋值为那个手指的id (这里忽略高低位正反的问题 方便理解)。
第二个手指头下来的时候
就变成了
1100 0000 0000 0000 ( 找第一个不为0的位置)。
第三次就变成了
1110 0000 0000 0000,
抬起第一个的时候 变成了
0110 0000 0000 0000。
然后第一个按下去的时候呢 就变成了
因为第一位是0 就改变为这个
1110 0000 0000 0000。
手指头的id是个数组, 比如你按下了三个手指头(还没抬的时候), 那么 id[0]=0 id[1]=1 id[2]=2 顺序是没问题的。
当抬起来第1个手指头的时候 这会还没是问题,毕竟你得等到move, 他才知道少了一个,这会还是 id[0]=0 id[1]=1 id[2]=2。
开始move的时候, 发现就俩了,这会这个就会发生变化, 这会就可能变成, id[0]=1 id[1]=2 这里的1和2 是id, 是不会变化的 但是存储手指头的数组变少了。
如果这会第一个手指头 又按下来了,又会恢复到 id[0]=0 id[1]=1 id[2]=2。
为什么新下来的手指头id测试出来是0,我没看过驱动层,我认为是驱动层的问题,我觉得可能是做了排序 从小到大来的。index 和id 不一定相等。
简单来说, 可以这么理解一个32位,被占用了就是1 ,没被占用就是0,就是按下是1, 抬起是0。 当按下来的时候会找哪一位不是0, 然后把自己放上去。
processRawTouches 进入到数据的架构
void TouchInputMapper::processRawTouches(bool timeout) {
// 如果这里模式是屏蔽触摸 那就啥都进不去了 可以禁止使用
if (mDeviceMode == DeviceMode::DISABLED) {
// Drop all input if the device is disabled.
cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
mCurrentCookedState.clear();
updateTouchSpots();
return;
}
const size_t N = mRawStatesPending.size();
size_t count;
for (count = 0; count < N; count++) {
const RawState& next = mRawStatesPending[count];
if (assignExternalStylusId(next, timeout)) {
break;
}
// All ready to go.
clearStylusDataPendingFlags();
mCurrentRawState.copyFrom(next);
if (mCurrentRawState.when < mLastRawState.when) {
mCurrentRawState.when = mLastRawState.when;
mCurrentRawState.readTime = mLastRawState.readTime;
}
//核心方法 数据加工
cookAndDispatch(mCurrentRawState.when, mCurrentRawState.readTime);
}
if (count != 0) {
mRawStatesPending.erase(mRawStatesPending.begin(), mRawStatesPending.begin() + count);
}
if (mExternalStylusDataPending) {
if (timeout) {
nsecs_t when = mExternalStylusFusionTimeout - STYLUS_DATA_LATENCY;
clearStylusDataPendingFlags();
mCurrentRawState.copyFrom(mLastRawState);
const nsecs_t readTime = when; // consider this synthetic event to be zero latency
cookAndDispatch(when, readTime);
} else if (mExternalStylusFusionTimeout == LLONG_MAX) {
mExternalStylusFusionTimeout = mExternalStylusState.when + TOUCH_DATA_TIMEOUT;
getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
}
}
}
cookAndDispatch 数据的加工
//native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
//为什么有这个方法, 因为触摸屏和基础的设置如果一模一样 就不会有该方法,但是很悲惨的是 底层设置,和真实的屏幕
//基本不一样,那么宽高之间有差距,那就需要对xy 之类的进行比例处理
//还有一种情况就是 旋转了屏幕 这时候就需要对应的换算了
mCurrentCookedState.clear();
applyExternalStylusButtonState(when);
bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
mCurrentRawState.rawPointerData.pointerCount != 0;
uint32_t policyFlags = 0;
bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
if (initialDown || buttonsPressed) {
if (mDeviceMode == DeviceMode::DIRECT) {
//小圆点的相关代码
getContext()->fadePointer();
}
if (mParameters.wake) {
policyFlags |= POLICY_FLAG_WAKE;
}
}
if (consumeRawTouches(when, readTime, policyFlags)) {
mCurrentRawState.rawPointerData.clear();
}
//核心方法
cookPointerData();
applyExternalStylusTouchState(when);
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
mSource, mViewport.displayId, policyFlags, mLastCookedState.buttonState,
mCurrentCookedState.buttonState);
if (mDeviceMode == DeviceMode::POINTER) {
for (BitSet32 idBits(mCurrentRawState.rawPointerData.touchingIdBits); !idBits.isEmpty();) {
uint32_t id = idBits.clearFirstMarkedBit();
const RawPointerData::Pointer& pointer =
mCurrentRawState.rawPointerData.pointerForId(id);
if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
mCurrentCookedState.stylusIdBits.markBit(id);
} else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER ||
pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
mCurrentCookedState.fingerIdBits.markBit(id);
} else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
mCurrentCookedState.mouseIdBits.markBit(id);
}
}
for (BitSet32 idBits(mCurrentRawState.rawPointerData.hoveringIdBits); !idBits.isEmpty();) {
uint32_t id = idBits.clearFirstMarkedBit();
const RawPointerData::Pointer& pointer =
mCurrentRawState.rawPointerData.pointerForId(id);
if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
mCurrentCookedState.stylusIdBits.markBit(id);
}
}
PointerUsage pointerUsage = mPointerUsage;
if (!mCurrentCookedState.stylusIdBits.isEmpty()) {
mCurrentCookedState.mouseIdBits.clear();
mCurrentCookedState.fingerIdBits.clear();
pointerUsage = PointerUsage::STYLUS;
} else if (!mCurrentCookedState.mouseIdBits.isEmpty()) {
mCurrentCookedState.fingerIdBits.clear();
pointerUsage = PointerUsage::MOUSE;
} else if (!mCurrentCookedState.fingerIdBits.isEmpty() ||
isPointerDown(mCurrentRawState.buttonState)) {
pointerUsage = PointerUsage::GESTURES;
}
dispatchPointerUsage(when, readTime, policyFlags, pointerUsage);
} else {
updateTouchSpots();
if (!mCurrentMotionAborted) {
dispatchButtonRelease(when, readTime, policyFlags);
dispatchHoverExit(when, readTime, policyFlags);
// 分发
dispatchTouches(when, readTime, policyFlags);
dispatchHoverEnterAndMove(when, readTime, policyFlags);
dispatchButtonPress(when, readTime, policyFlags);
}
if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
mCurrentMotionAborted = false;
}
}
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, readTime, getDeviceId(), mSource,
mViewport.displayId, policyFlags, mLastCookedState.buttonState,
mCurrentCookedState.buttonState);
mCurrentRawState.rawVScroll = 0;
mCurrentRawState.rawHScroll = 0;
mLastRawState.copyFrom(mCurrentRawState);
mLastCookedState.copyFrom(mCurrentCookedState);
void TouchInputMapper::cookPointerData() {
uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
mCurrentCookedState.cookedPointerData.clear();
mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
mCurrentCookedState.cookedPointerData.hoveringIdBits =
mCurrentRawState.rawPointerData.hoveringIdBits;
mCurrentCookedState.cookedPointerData.touchingIdBits =
mCurrentRawState.rawPointerData.touchingIdBits;
mCurrentCookedState.cookedPointerData.canceledIdBits =
mCurrentRawState.rawPointerData.canceledIdBits;
if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
mCurrentCookedState.buttonState = 0;
} else {
mCurrentCookedState.buttonState = mCurrentRawState.buttonState;
}
for (uint32_t i = 0; i < currentPointerCount; i++) {
const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];
//省略
// 旋转角度 因为涉及到旋转后的宽高切换 三角函数的换算
float tilt;
float orientation;
if (mHaveTilt) {
float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
} else {
tilt = 0;
switch (mCalibration.orientationCalibration) {
case Calibration::OrientationCalibration::INTERPOLATED:
orientation = in.orientation * mOrientationScale;
break;
case Calibration::OrientationCalibration::VECTOR: {
int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
int32_t c2 = signExtendNybble(in.orientation & 0x0f);
if (c1 != 0 || c2 != 0) {
orientation = atan2f(c1, c2) * 0.5f;
float confidence = hypotf(c1, c2);
float scale = 1.0f + confidence / 16.0f;
touchMajor *= scale;
touchMinor /= scale;
toolMajor *= scale;
toolMinor /= scale;
} else {
orientation = 0;
}
break;
}
default:
orientation = 0;
}
}
// Distance
float distance;
switch (mCalibration.distanceCalibration) {
case Calibration::DistanceCalibration::SCALED:
distance = in.distance * mDistanceScale;
break;
default:
distance = 0;
}
// Coverage
int32_t rawLeft, rawTop, rawRight, rawBottom;
switch (mCalibration.coverageCalibration) {
case Calibration::CoverageCalibration::BOX:
rawLeft = (in.toolMinor & 0xffff0000) >> 16;
rawRight = in.toolMinor & 0x0000ffff;
rawBottom = in.toolMajor & 0x0000ffff;
rawTop = (in.toolMajor & 0xffff0000) >> 16;
break;
default:
rawLeft = rawTop = rawRight = rawBottom = 0;
break;
}
//核心 x和y 触摸屏就关注手指头和xy
float xTransformed = in.x, yTransformed = in.y;
mAffineTransform.applyTo(xTransformed, yTransformed);
rotateAndScale(xTransformed, yTransformed);
float left, top, right, bottom;
switch (mSurfaceOrientation) {
//根据角度去转换对应的数据
case DISPLAY_ORIENTATION_90:
left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
orientation -= M_PI_2;
if (mOrientedRanges.haveOrientation &&
orientation < mOrientedRanges.orientation.min) {
orientation +=
(mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
}
break;
case DISPLAY_ORIENTATION_180:
left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
orientation -= M_PI;
if (mOrientedRanges.haveOrientation &&
orientation < mOrientedRanges.orientation.min) {
orientation +=
(mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
}
break;
case DISPLAY_ORIENTATION_270:
left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
orientation += M_PI_2;
if (mOrientedRanges.haveOrientation &&
orientation > mOrientedRanges.orientation.max) {
orientation -=
(mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
}
break;
default://mXScale缩放参数
left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
break;
}
// Write output coords.
PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
out.clear();
out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) {
out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
} else {
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
}
// Write output relative fields if applicable.
uint32_t id = in.id;
if (mSource == AINPUT_SOURCE_TOUCHPAD &&
mLastCookedState.cookedPointerData.hasPointerCoordsForId(id)) {
const PointerCoords& p = mLastCookedState.cookedPointerData.pointerCoordsForId(id);
float dx = xTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_X);
float dy = yTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_Y);
out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, dx);
out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, dy);
}
PointerProperties& properties = mCurrentCookedState.cookedPointerData.pointerProperties[i];
properties.clear();
properties.id = id;
properties.toolType = in.toolType;
mCurrentCookedState.cookedPointerData.idToIndex[id] = i;
mCurrentCookedState.cookedPointerData.validIdBits.markBit(id);
}
}
dispatchTouches 触摸点的派发 滑动 按下 的计算
void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
// 是down 还是move 和上一次有很大的关系
BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = mCurrentCookedState.buttonState;
//当前触点 是上一次的触点 也就说没有手指的增加 那么判断为move AMOTION_EVENT_ACTION_MOVE
//这里指的是 上次是1110 这次也是1110
if (currentIdBits == lastIdBits) {
if (!currentIdBits.isEmpty()) {
dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1,
mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
} else {
//抬起 按下 移动 的情况 如果和上次的触点不一致 有可能也是move 比如这次是1110 但是变为了1111 那之前的 也没抬起 人也在继续move upIdBits 取反再与 都是1则为1 否则是0
//分别是 up down move 的计算 看看谁抬起了 按下了和move了
BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
BitSet32 dispatchedIdBits(lastIdBits.value);
//判断是否是需要移动的
bool moveNeeded =
updateMovedPointers(mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
mLastCookedState.cookedPointerData.pointerProperties,
mLastCookedState.cookedPointerData.pointerCoords,
mLastCookedState.cookedPointerData.idToIndex, moveIdBits);
if (buttonState != mLastCookedState.buttonState) {
moveNeeded = true;
}
while (!upIdBits.isEmpty()) {
uint32_t upId = upIdBits.clearFirstMarkedBit();
bool isCanceled = mCurrentCookedState.cookedPointerData.canceledIdBits.hasBit(upId);
//分发CANCELED
dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0,
isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0,
mLastCookedState.cookedPointerData.pointerProperties,
mLastCookedState.cookedPointerData.pointerCoords,
mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId,
mOrientedXPrecision, mOrientedYPrecision, mDownTime);
dispatchedIdBits.clearBit(upId);
mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId);
}
if (moveNeeded && !moveIdBits.isEmpty()) {
ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
//分发move
dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
metaState, buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, -1,
mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
while (!downIdBits.isEmpty()) {
uint32_t downId = downIdBits.clearFirstMarkedBit();
dispatchedIdBits.markBit(downId);
if (dispatchedIdBits.count() == 1) {
mDownTime = when;
}
//分发down
dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_DOWN,
0, 0, metaState, buttonState, 0,
mCurrentCookedState.cookedPointerData.pointerProperties,
mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits,
downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
}
}
dispatchMotion 数据的派发
//native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
//组合出来一个 MotionEvent
void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
uint32_t source, int32_t action, int32_t actionButton,
int32_t flags, int32_t metaState, int32_t buttonState,
int32_t edgeFlags, const PointerProperties* properties,
const PointerCoords* coords, const uint32_t* idToIndex,
BitSet32 idBits, int32_t changedId, float xPrecision,
float yPrecision, nsecs_t downTime) {
PointerCoords pointerCoords[MAX_POINTERS];
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
while (!idBits.isEmpty()) {
uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = idToIndex[id];
pointerProperties[pointerCount].copyFrom(properties[index]);
pointerCoords[pointerCount].copyFrom(coords[index]);
if (changedId >= 0 && id == uint32_t(changedId)) {
//第一个手指头按下是down 剩下的按下去就会加上掩码 比如变为了Action_point_down(1/2/3)这种
action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
}
pointerCount += 1;
}
ALOG_ASSERT(pointerCount != 0);
if (changedId >= 0 && pointerCount == 1) {
if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
action = AMOTION_EVENT_ACTION_DOWN;
} else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
action = AMOTION_EVENT_ACTION_CANCEL;
} else {
action = AMOTION_EVENT_ACTION_UP;
}
} else {
ALOG_ASSERT(false);
}
}
float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
if (mDeviceMode == DeviceMode::POINTER) {
auto [x, y] = getMouseCursorPosition();
xCursorPosition = x;
yCursorPosition = y;
}
const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
const int32_t deviceId = getDeviceId();
std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
std::for_each(frames.begin(), frames.end(),
[this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });
//组装为 NotifyMotionArgs
NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
policyFlags, action, actionButton, flags, metaState, buttonState,
MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
downTime, std::move(frames));
//native/services/inputflinger/reader/include/InputReader.h
// 这里的getListener 实际是 InputReader.cpp 里的 mReader->mQueuedListener.get();
getListener()->notifyMotion(&args);
}
getListener() 的由来。
这里的getListener 实际是 InputReader.cpp 里的 mReader->mQueuedListener.get();
在InputReader的构造里构建出来的 传入的 listener。
QueuedInputListener 的实现在 native/services/inputflinger/InputListener.cpp 里面。其实就是 其实就是InputDispatcher的一层包装。
//native/services/inputflinger/reader/include/InputReader.h
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener)
: mContext(this),
mEventHub(eventHub),
mPolicy(policy),
mGlobalMetaState(0),
mLedMetaState(AMETA_NUM_LOCK_ON),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
//listener 就是外面传进来的 mClassifier 在追一下 其实就是InputDispatcher的一层包装
mQueuedListener = new QueuedInputListener(listener);
}
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
//InputDispatcher 实现 InputDispatcherInterface::InputListenerInterface
mDispatcher = createInputDispatcher(dispatcherPolicy);
//InputClassifier 继承实现 InputClassifierInterface ::InputListenerInterface
mClassifier = new InputClassifier(mDispatcher);
//也就说其实他俩都实现了InputListenerInterface
mReader = createInputReader(readerPolicy, mClassifier);
}
//native/services/inputflinger/InputListener.cpp
void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
traceEvent(__func__, args->id);
// 就往队列里加了消息
mArgsQueue.push_back(new NotifyMotionArgs(*args));
}
//初始化构建的时候构建了 mInnerListener 也就是 InputDispatcher
QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
mInnerListener(innerListener) {
}
//直到有人调用 flush 才会将消息 通知出去
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
listener->notifyMotion(this);
}
到这一步,需要联系loopOnce()代码去看。notifyMotion()将数据刷入了mArgsQueue。flush() 将调用NotifyMotionArgs.notifyMotion(),删除数据,调用listener 也就是 InputDispatcher的notifyMotion()。
在下一步就是进入 InputDispatcher.notifyMotion()。涉及到入队的操作,也就是我们常说的IQ,
数据处理这部分其实在我看来是很繁琐的一套流程,涉及多次结构体的转换,所以我一般对这里的概念就是EventHub 读了dev/input 下的数据,然后经过一套转换,把数据存进了IQ。