1. 多指触控协议
多指触控协议有 2 种:
> A类: 处理无关联的接触: 用于直接发送原始数据;
> B类: 处理跟踪识别类的接触: 通过事件slot发送相关联的独立接触更新。
B协议可以使用一个ID来标识触点,可以减少上报到用户空间的数据量,这个ID(ABS_MT_TRACKING_ID)可以有硬件提供或者从原始数据计算而得。而InputReader 就是处理这些数据
通过下列命令可以dump :adb shell getevent -tl
[ 1029.903648] /dev/input/event1: EV_SYN 0004 00000405
[ 1029.903648] /dev/input/event1: EV_SYN 0005 35c02ec5
[ 1029.903648] /dev/input/event1: EV_ABS ABS_MT_SLOT 00000000
[ 1029.903648] /dev/input/event1: EV_ABS ABS_MT_POSITION_X 00000173 第一个手指X坐标
[ 1029.903648] /dev/input/event1: EV_ABS ABS_MT_SLOT 00000001
[ 1029.903648] /dev/input/event1: EV_ABS ABS_MT_POSITION_X 00000321 第二个手指X坐标
[ 1029.903648] /dev/input/event1: EV_SYN SYN_REPORT 00000000 [ 1031.902947] /dev/input/event1: EV_SYN 0004 00000407
[ 1031.902947] /dev/input/event1: EV_SYN 0005 35b8a020
[ 1031.902947] /dev/input/event1: EV_ABS ABS_MT_SLOT 00000000 第一个手指有事件
[ 1031.902947] /dev/input/event1: EV_ABS ABS_MT_TRACKING_ID ffffffff TRACKING_ID为-1代表第一个手指抬起消失
[ 1031.902947] /dev/input/event1: EV_SYN SYN_REPORT 00000000
[ 1032.024946] /dev/input/event1: EV_SYN 0004 00000408
[ 1032.024946] /dev/input/event1: EV_SYN 0005 016372d8
[ 1032.024946] /dev/input/event1: EV_ABS ABS_MT_SLOT 00000001 第二个手指有事件
[ 1032.024946] /dev/input/event1: EV_ABS ABS_MT_POSITION_Y 0000016c 第二个 Y坐标
[ 1032.024946] /dev/input/event1: EV_SYN SYN_REPORT 00000000
[ 1032.907686] /dev/input/event1: EV_SYN 0004 00000408
[ 1032.907686] /dev/input/event1: EV_SYN 0005 35ebac8c
[ 1032.907686] /dev/input/event1: EV_ABS ABS_MT_TRACKING_ID ffffffff 第二个手指消失抬起
[ 1032.907686] /dev/input/event1: EV_KEY BTN_TOUCH UP 抬起
[ 1032.907686] /dev/input/event1: EV_KEY BTN_TOOL_FINGER UP
[ 1032.907686] /dev/input/event1: EV_SYN SYN_REPORT 00000000
其中分为 3 个类型,为 EV_SYN、EV_ABS 和 EV_KEY
0004:代表一个事件开始(不必要)
0005:代表一个事件开始(不必要)
SYN_REPORT:代表一个事件的结束 (必要)
ABS_MT_SLOT:
本质代表者不同手指,它的value代表手指id
ABS_MT_TRACKING_ID:
类型B特有的,实际上,每个slot会和一个ID相对应,一个非负数的表示一次接触,-1表示这是一个无用的slot(或者理解为一次接触的结束) 。
BTN_TOUCH
触碰按键。其值是DOWN或者UP。
2. InputReader 处理触摸数据
/frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader 监听设备的数据,getEvents()是阻塞的,只有当有事件或者被wake才会被唤醒向下执行。
86 void InputReader::loopOnce() {
87 int32_t oldGeneration;
88 int32_t timeoutMillis;
89 bool inputDevicesChanged = false;
90 std::vector<InputDeviceInfo> inputDevices;
91 { // acquire lock
92 std::scoped_lock _l(mLock);
93
94 oldGeneration = mGeneration;
95 timeoutMillis = -1;
96
。。。。。
107
// 1)从eventhub 中获取驱动上报的事件 getEvents
108 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
109
110 { // acquire lock
111 std::scoped_lock _l(mLock);
112 mReaderIsAliveCondition.notify_all();
113
114 if (count) {
// 2)处理上报的数据:processEventsLocked
115 processEventsLocked(mEventBuffer, count);
116 }
117
。。。。
// 3)观察者队列去flush,处理全部的事件:flush
147 mQueuedListener->flush();
148 }
// 1)从eventhub 中获取驱动上报的事件 getEvents
1461 size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
1462 ALOG_ASSERT(bufferSize >= 1);
1463
1464 std::scoped_lock _l(mLock);
1465
1466 struct input_event readBuffer[bufferSize];
1467
1468 RawEvent* event = buffer;
1469 size_t capacity = bufferSize;
1470 bool awoken = false;
1471 for (;;) {
1472 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);。。。。。。
1548 // Grab the next input event.
1549 bool deviceChanged = false;// 设置 mPendingEventCount 值,则满足下列条件
1550 while (mPendingEventIndex < mPendingEventCount) {
1551 const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];// 通过fd 获取到对应的 Device,创建对象为 std::make_unique<Device>(fd
1577 Device* device = getDeviceByFdLocked(eventItem.data.fd);1605 if (eventItem.events & EPOLLIN) {
// 读取对应fd 的数据
1606 int32_t readSize =
1607 read(device->fd, readBuffer, sizeof(struct input_event) * capacity);。。。。。
1621 } else {
1622 int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
1623
1624 size_t count = size_t(readSize) / sizeof(struct input_event);
1625 for (size_t i = 0; i < count; i++) {
1626 struct input_event& iev = readBuffer[i];
1627 event->when = processEventTimestamp(iev);
1628 event->readTime = systemTime(SYSTEM_TIME_MONOTONIC);
1629 event->deviceId = deviceId;
// 将上报的type 和 code value 保存到 event 中,遍历所有然后退出
1630 event->type = iev.type;
1631 event->code = iev.code;
1632 event->value = iev.value;
1633 event += 1;
1634 capacity -= 1;
1635 }
1636 if (capacity == 0) {
1637 // The result buffer is full. Reset the pending event index
1638 // so we will try to read the device again on the next iteration.
1639 mPendingEventIndex -= 1;
1640 break;
1641 }
1642 }
。。。。。。
// 首先是epoll 监听底层的事件
1688 int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
1689
1690 mLock.lock(); // reacquire lock after poll
。。。。。。。
1708 } else {
1709 // Some events occurred.
// 如果有事件的话 设置 mPendingEventCount 值
1710 mPendingEventCount = size_t(pollResult);
1711 }
1712 }
1713
1714 // All done, return the number of events we read.
1715 return event - buffer;
1716 }
// 将上报的type 和 code value 保存到 event 中,遍历所有然后return退出,数据给到 processEventsLocked 处理。
// 2)处理上报的数据:processEventsLocked
- processEventsLocked()函数中会遍历所有的事件,分别进行处理。其处理的事件类型分为四种:原始输入事件、设备加载事件、设备卸载事件及FINISHED_DEVICE_SCAN事件。
/frameworks/native/services/inputflinger/reader/InputReader.cpp
150 void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {// 遍历处理所有的事件 rawEvent
151 for (const RawEvent* rawEvent = rawEvents; count;) {
152 int32_t type = rawEvent->type;
153 size_t batchSize = 1;
154 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
// 获取到设备的id
155 int32_t deviceId = rawEvent->deviceId;
156 while (batchSize < count) {
157 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
158 rawEvent[batchSize].deviceId != deviceId) {
159 break;
160 }
161 batchSize += 1;
162 }
163 #if DEBUG_RAW_EVENTS
164 ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
165 #endif
// 处理事件 processEventsForDeviceLocked
166 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);================
296 void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
297 size_t count) {// 通过hubid 找到对应的 InputDevice
298 auto deviceIt = mDevices.find(eventHubId);
299 if (deviceIt == mDevices.end()) {
300 ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
301 return;
302 }
303
304 std::shared_ptr<InputDevice>& device = deviceIt->second;
305 if (device->isIgnored()) {
306 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
307 return;
308 }
309 // 通过 InputDevice 去处理事件process
310 device->process(rawEvents, count);
311 }
// 通过 InputDevice 去处理事件process。
根据事件获得相应的设备类型,然后将事件交给相应的设备处理,给触摸设备相关的类去处理。
/frameworks/native/services/inputflinger/reader/InputDevice.cpp
375 void InputDevice::process(const RawEvent* rawEvents, size_t count) {// 遍历所有的事件
381 for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
382 #if DEBUG_RAW_EVENTS
383 ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
384 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when);
385 #endif
386
387 if (mDropUntilNextSync) {
388 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
389 mDropUntilNextSync = false;
390 #if DEBUG_RAW_EVENTS
391 ALOGD("Recovered from input event buffer overrun.");
392 #endif
393 } else {
394 #if DEBUG_RAW_EVENTS
395 ALOGD("Dropped input event while waiting for next input sync.");
396 #endif
397 }
// 如果事件类型是 SYN_DROPPED,则drop 这个事件
398 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
399 ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
400 mDropUntilNextSync = true;
401 reset(rawEvent->when);
402 } else {// 遍历所有的mapper 去处理 rawevent
403 for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
404 mapper.process(rawEvent);
405 });
406 }
407 --count;
408 }
409 }========
// 遍历所有的mapper 去处理 rawevent
// 前面 addEventubDevice 的时候,将其MultiTouchInputMapper 增加到了mapper 中
195 inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
196 std::function<void(InputMapper&)> f) {
197 auto deviceIt = mDevices.find(eventHubDevice);
198 if (deviceIt != mDevices.end()) {
199 auto& devicePair = deviceIt->second;
200 auto& mappers = devicePair.second;
201 for (auto& mapperPtr : mappers) {
202 f(*mapperPtr);
203 }
204 }
205 }
调用 MultiTouchInputMapper 的process 方法
/frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
238 void MultiTouchInputMapper::process(const RawEvent* rawEvent) {// 2-1)TouchInputMapper 先进行处理 process
239 TouchInputMapper::process(rawEvent);
240 // 2-2)MultiTouchMotionAccumulator 处理rawEvent:process
241 mMultiTouchMotionAccumulator.process(rawEvent);
242 }
其实是先处理process,然后再去
// 2-2)MultiTouchMotionAccumulator 处理rawEvent:process
通过 MultiTouchMotionAccumulator.process处理了
85 void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
86 if (rawEvent->type == EV_ABS) {
87 bool newSlot = false;
。。。。。。。
105 } else {// mCurrentSlot 为当前的手指
106 Slot* slot = &mSlots[mCurrentSlot];
107 // If mUsingSlotsProtocol is true, it means the raw pointer has axis info of
108 // ABS_MT_TRACKING_ID and ABS_MT_SLOT, so driver should send a valid trackingId while
109 // updating the slot.
110 if (!mUsingSlotsProtocol) {
// 设置为true
111 slot->mInUse = true;
112 }
113
114 switch (rawEvent->code) {
// 设置对应的xy 轴值
115 case ABS_MT_POSITION_X:
116 slot->mAbsMTPositionX = rawEvent->value;
117 warnIfNotInUse(*rawEvent, *slot);
118 break;
119 case ABS_MT_POSITION_Y:
120 slot->mAbsMTPositionY = rawEvent->value;
121 warnIfNotInUse(*rawEvent, *slot);
122 break;
123 case ABS_MT_TOUCH_MAJOR:
124 slot->mAbsMTTouchMajor = rawEvent->value;
125 break;
126 case ABS_MT_TOUCH_MINOR:
127 slot->mAbsMTTouchMinor = rawEvent->value;
128 slot->mHaveAbsMTTouchMinor = true;
129 break;
130 case ABS_MT_WIDTH_MAJOR:
131 slot->mAbsMTWidthMajor = rawEvent->value;
132 break;
133 case ABS_MT_WIDTH_MINOR:
134 slot->mAbsMTWidthMinor = rawEvent->value;
135 slot->mHaveAbsMTWidthMinor = true;
136 break;
137 case ABS_MT_ORIENTATION:
138 slot->mAbsMTOrientation = rawEvent->value;
139 break;// trackid 为手指数,表示第几个手指
140 case ABS_MT_TRACKING_ID:
141 if (mUsingSlotsProtocol && rawEvent->value < 0) {
142 // The slot is no longer in use but it retains its previous contents,
143 // which may be reused for subsequent touches.
144 slot->mInUse = false;
145 } else {
146 slot->mInUse = true;
// 设置 mAbsMTTrackingId
147 slot->mAbsMTTrackingId = rawEvent->value;
148 }
149 break;
150 case ABS_MT_PRESSURE:
151 slot->mAbsMTPressure = rawEvent->value;
152 break;
153 case ABS_MT_DISTANCE:
154 slot->mAbsMTDistance = rawEvent->value;
155 break;
156 case ABS_MT_TOOL_TYPE:
157 slot->mAbsMTToolType = rawEvent->value;
158 slot->mHaveAbsMTToolType = true;
159 break;
160 }
161 }// 如果类型是结束的话,则设置 mCurrentSlot 增加1
162 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
163 // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
164 mCurrentSlot += 1;
165 }
166 }
// 2-1)TouchInputMapper 先进行处理 process
处理是上一次的结果,通过 MultiTouchMotionAccumulator.process处理了
/frameworks/native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
1425 void TouchInputMapper::process(const RawEvent* rawEvent) {
1426 mCursorButtonAccumulator.process(rawEvent);
1427 mCursorScrollAccumulator.process(rawEvent);
1428 mTouchButtonAccumulator.process(rawEvent);
1429 // 如果事件是结束了的话,则执行sync
1430 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
1431 sync(rawEvent->when, rawEvent->readTime);
1432 }
1433 }=========
1435 void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
1436 // Push a new state.
1437 mRawStatesPending.emplace_back();
1438
1439 RawState& next = mRawStatesPending.back();
1440 next.clear();
1441 next.when = when;
1442 next.readTime = readTime;
1443
1444 // Sync button state.
1445 next.buttonState =
1446 mTouchButtonAccumulator.getButtonState() | mCursorButtonAccumulator.getButtonState();
1447
1448 // Sync scroll
1449 next.rawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
1450 next.rawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
1451 mCursorScrollAccumulator.finishSync();
1452 // 2-1-1)同步触摸事件 syncTouch
1454 syncTouch(when, &next);
1455
1456 // The last RawState is the actually second to last, since we just added a new state
1457 const RawState& last =
1458 mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1];
1459
1460 // Assign pointer ids.
1461 if (!mHavePointerIds) {
1462 assignPointerIds(last, next);
1463 }
1464 // 打开开关会打印下列的log,对应的 pointerCount 手指数量
1465 #if DEBUG_RAW_EVENTS
1466 ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
1467 "hovering ids 0x%08x -> 0x%08x, canceled ids 0x%08x",
1468 last.rawPointerData.pointerCount, next.rawPointerData.pointerCount,
1469 last.rawPointerData.touchingIdBits.value, next.rawPointerData.touchingIdBits.value,
1470 last.rawPointerData.hoveringIdBits.value, next.rawPointerData.hoveringIdBits.value,
1471 next.rawPointerData.canceledIdBits.value);
1472 #endif
1473
1474 if (!next.rawPointerData.touchingIdBits.isEmpty() &&
1475 !next.rawPointerData.hoveringIdBits.isEmpty() &&
1476 last.rawPointerData.hoveringIdBits != next.rawPointerData.hoveringIdBits) {
1477 ALOGI("Multi-touch contains some hovering ids 0x%08x",
1478 next.rawPointerData.hoveringIdBits.value);
1479 }
1480 // 2-1-2)处理触摸事件:processRawTouches
1481 processRawTouches(false /*timeout*/);
1482 }
input设备类型有很多种,以上只是触摸设备的inputmapper:MultiTouchInputMapper,还有下列几种
- 键盘类设备:KeyboardInputMapper
- 触摸屏设备:MultiTouchInputMapper或SingleTouchInputMapper
- 鼠标类设备:CursorInputMapper
// 2-1-1)同步触摸事件 syncTouch,调用的是子类的方法
/frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
最大的手指的数量为 16 个
178 #define MAX_POINTERS 16
258 void MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
/// 获取的数量值为配置的值
259 size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
260 size_t outCount = 0;
261 BitSet32 newPointerIdBits;
262 mHavePointerIds = true;
263 // 获取到对应的slot
264 for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
265 const MultiTouchMotionAccumulator::Slot* inSlot =
266 mMultiTouchMotionAccumulator.getSlot(inIndex);
267 if (!inSlot->isInUse()) {
268 continue;
269 }。。。。
// 如果超过最大18个手指,则break
283 if (outCount >= MAX_POINTERS) {
284 #if DEBUG_POINTERS
285 ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
286 "ignoring the rest.",
287 getDeviceName().c_str(), MAX_POINTERS);
288 #endif
289 break; // too many fingers!
290 }
291 // 获取到 RawPointerData::Pointer,设置对应的手指的参数
292 RawPointerData::Pointer& outPointer = outState->rawPointerData.pointers[outCount];
// 设置xy 轴的值
293 outPointer.x = inSlot->getX();
294 outPointer.y = inSlot->getY();
295 outPointer.pressure = inSlot->getPressure();
296 outPointer.touchMajor = inSlot->getTouchMajor();
297 outPointer.touchMinor = inSlot->getTouchMinor();
298 outPointer.toolMajor = inSlot->getToolMajor();
299 outPointer.toolMinor = inSlot->getToolMinor();
300 outPointer.orientation = inSlot->getOrientation();
301 outPointer.distance = inSlot->getDistance();
302 outPointer.tiltX = 0;
303 outPointer.tiltY = 0;
304
305 outPointer.toolType = inSlot->getToolType();
306 if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
307 outPointer.toolType = mTouchButtonAccumulator.getToolType();
308 if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
309 outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
310 }
311 }。。。。
318 // Assign pointer id using tracking id if available.
319 if (mHavePointerIds) {
320 int32_t trackingId = inSlot->getTrackingId();
321 int32_t id = -1;
322 if (trackingId >= 0) {
323 for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty();) {
324 uint32_t n = idBits.clearFirstMarkedBit();
325 if (mPointerTrackingIdMap[n] == trackingId) {
326 id = n;
327 }
328 }
329
330 if (id < 0 && !mPointerIdBits.isFull()) {
331 id = mPointerIdBits.markFirstUnmarkedBit();
332 mPointerTrackingIdMap[id] = trackingId;
333 }
334 }
335 if (id < 0) {
336 mHavePointerIds = false;
337 outState->rawPointerData.clearIdBits();
338 newPointerIdBits.clear();
339 } else {
340 outPointer.id = id;
341 outState->rawPointerData.idToIndex[id] = outCount;
342 outState->rawPointerData.markIdBit(id, isHovering);
343 newPointerIdBits.markBit(id);
344 }
345 }
346 outCount += 1;
347 }
348
349 outState->rawPointerData.pointerCount = outCount;
350 mPointerIdBits = newPointerIdBits;
351
352 mMultiTouchMotionAccumulator.finishSync();
353 }
// 2-1-2)处理触摸事件:processRawTouches
//将RawState的数据复制到 mCurrentRawState
1484 void TouchInputMapper::processRawTouches(bool timeout) {
1485 if (mDeviceMode == DeviceMode::DISABLED) {
1486 // Drop all input if the device is disabled.
1487 cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
1488 mCurrentCookedState.clear();
1489 updateTouchSpots();
1490 return;
1491 }// 遍历所有的 RawState
1497 const size_t N = mRawStatesPending.size();
1498 size_t count;
1499 for (count = 0; count < N; count++) {
1500 const RawState& next = mRawStatesPending[count];1504 if (assignExternalStylusId(next, timeout)) {
1505 break;
1506 }
1507
1508 // All ready to go.
1509 clearStylusDataPendingFlags();
//将RawState的数据复制到 mCurrentRawState
1510 mCurrentRawState.copyFrom(next);
1511 if (mCurrentRawState.when < mLastRawState.when) {
1512 mCurrentRawState.when = mLastRawState.when;
1513 mCurrentRawState.readTime = mLastRawState.readTime;
1514 }// 处理这个数据并分发:cookAndDispatch
1515 cookAndDispatch(mCurrentRawState.when, mCurrentRawState.readTime);
1516 }
// 处理这个数据并分发:cookAndDispatch
1538 void TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t readTime) {
1539 // Always start with a clean state.
1540 mCurrentCookedState.clear();
1541
1542 // Apply stylus buttons to current raw state.
1543 applyExternalStylusButtonState(when);
1544
1545 // Handle policy on initial down or hover events.
1546 bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
1547 mCurrentRawState.rawPointerData.pointerCount != 0;
1548
1549 uint32_t policyFlags = 0;
1550 bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
1551 if (initialDown || buttonsPressed) {
1552 // If this is a touch screen, hide the pointer on an initial down.
1553 if (mDeviceMode == DeviceMode::DIRECT) {
1554 getContext()->fadePointer();
1555 }
1556
1557 if (mParameters.wake) {
1558 policyFlags |= POLICY_FLAG_WAKE;
1559 }
1560 }
1564 if (consumeRawTouches(when, readTime, policyFlags)) {
1565 mCurrentRawState.rawPointerData.clear();
1566 }// 处理pointer 数据:cookPointerData
1571 cookPointerData();// 设备类型是 DIRECT
1582 if (mDeviceMode == DeviceMode::POINTER) {
。。。。
1622 } else {
1623 updateTouchSpots();
1624
1625 if (!mCurrentMotionAborted) {
1626 dispatchButtonRelease(when, readTime, policyFlags);
1627 dispatchHoverExit(when, readTime, policyFlags);
// 分发tounch 事件 dispatchTouches
1628 dispatchTouches(when, readTime, policyFlags);
1629 dispatchHoverEnterAndMove(when, readTime, policyFlags);
1630 dispatchButtonPress(when, readTime, policyFlags);
1631 }
// 处理pointer 数据:cookPointerData
2075 void TouchInputMapper::cookPointerData() {
// 设置按下手指的数量
2076 uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
2077
2078 mCurrentCookedState.cookedPointerData.clear();
2079 mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
2080 mCurrentCookedState.cookedPointerData.hoveringIdBits =
2081 mCurrentRawState.rawPointerData.hoveringIdBits;
2082 mCurrentCookedState.cookedPointerData.touchingIdBits =
2083 mCurrentRawState.rawPointerData.touchingIdBits;
2084 mCurrentCookedState.cookedPointerData.canceledIdBits =
2085 mCurrentRawState.rawPointerData.canceledIdBits;
。。。。
2095 for (uint32_t i = 0; i < currentPointerCount; i++) {
2096 const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];
2097
2098 // Size
2099 float touchMajor, touchMinor, toolMajor, toolMinor, size;
2100 switch (mCalibration.sizeCalibration) {
2101 case Calibration::SizeCalibration::GEOMETRIC:
2102 case Calibration::SizeCalibration::DIAMETER:
2103 case Calibration::SizeCalibration::BOX:
2104 case Calibration::SizeCalibration::AREA:
。。。。
// 设置对应的touchMajor
2112 } else if (mRawPointerAxes.touchMajor.valid) {
2113 toolMajor = touchMajor = in.touchMajor;
2114 toolMinor = touchMinor =
2115 mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
2116 size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
2117 : in.touchMajor;
.。。。。。
// 进行仿射变换
2250 float xTransformed = in.x, yTransformed = in.y;
2251 mAffineTransform.applyTo(xTransformed, yTransformed);
2252 rotateAndScale(xTransformed, yTransformed);
。。。。。。// 将其数据保存到 mCurrentCookedState.cookedPointerData.pointerCoords
2302 // Write output coords.
2303 PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
2304 out.clear();
2305 out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
2306 out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
2307 out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
2308 out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
2309 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
2310 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
2311 out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
2312 out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
2313 out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
// 分发tounch 事件 dispatchTouches
1904 void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
1905 BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
1906 BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
1907 int32_t metaState = getContext()->getGlobalMetaState();
1908 int32_t buttonState = mCurrentCookedState.buttonState;
1909
1910 if (currentIdBits == lastIdBits) {
。。。。。
1921 } else {// 判断是up,down还是move 事件
1924 BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
1925 BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
1926 BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
1927 BitSet32 dispatchedIdBits(lastIdBits.value);
1928
1929 // Update last coordinates of pointers that have moved so that we observe the new
1930 // pointer positions at the same time as other pointers that have just gone up.
1931 bool moveNeeded =
1932 updateMovedPointers(mCurrentCookedState.cookedPointerData.pointerProperties,
1933 mCurrentCookedState.cookedPointerData.pointerCoords,
1934 mCurrentCookedState.cookedPointerData.idToIndex,
1935 mLastCookedState.cookedPointerData.pointerProperties,
1936 mLastCookedState.cookedPointerData.pointerCoords,
1937 mLastCookedState.cookedPointerData.idToIndex, moveIdBits);
1938 if (buttonState != mLastCookedState.buttonState) {
1939 moveNeeded = true;
1940 }
1941 // 遍历所有的up 事件
1943 while (!upIdBits.isEmpty()) {
// 对应的up 的按钮:upId
1944 uint32_t upId = upIdBits.clearFirstMarkedBit();
1945 bool isCanceled = mCurrentCookedState.cookedPointerData.canceledIdBits.hasBit(upId);
1946 if (isCanceled) {
1947 ALOGI("Canceling pointer %d for the palm event was detected.", upId);
1948 }// up 的事件为 AMOTION_EVENT_ACTION_POINTER_UP,事件保存再 cookedPointerData.pointerCoords:走dispatchMotion 方法
1949 dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0,
1950 isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0,
1951 mLastCookedState.cookedPointerData.pointerProperties,
1952 mLastCookedState.cookedPointerData.pointerCoords,
1953 mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId,
1954 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
1955 dispatchedIdBits.clearBit(upId);
1956 mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId);
1957 }
// up 的事件为 AMOTION_EVENT_ACTION_POINTER_UP,事件保存再 cookedPointerData.pointerCoords:走dispatchMotion 方法
3601 void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
3602 uint32_t source, int32_t action, int32_t actionButton,
3603 int32_t flags, int32_t metaState, int32_t buttonState,
3604 int32_t edgeFlags, const PointerProperties* properties,
3605 const PointerCoords* coords, const uint32_t* idToIndex,
3606 BitSet32 idBits, int32_t changedId, float xPrecision,
3607 float yPrecision, nsecs_t downTime) {
3608 PointerCoords pointerCoords[MAX_POINTERS];
3609 PointerProperties pointerProperties[MAX_POINTERS];
3610 uint32_t pointerCount = 0;
3611 while (!idBits.isEmpty()) {
3612 uint32_t id = idBits.clearFirstMarkedBit();
3613 uint32_t index = idToIndex[id];
3614 pointerProperties[pointerCount].copyFrom(properties[index]);// 将数据保存到pointerCoords 中
3615 pointerCoords[pointerCount].copyFrom(coords[index]);
3616 // changedId 为up 的事件
3617 if (changedId >= 0 && id == uint32_t(changedId)) {
3618 action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
3619 }
3620
3621 pointerCount += 1;
3622 }
3623
3624 ALOG_ASSERT(pointerCount != 0);
3625 // 如果是单指的话,则将up事件更换为 AMOTION_EVENT_ACTION_UP
3626 if (changedId >= 0 && pointerCount == 1) {
3627 // Replace initial down and final up action.
3628 // We can compare the action without masking off the changed pointer index
3629 // because we know the index is 0.
3630 if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
3631 action = AMOTION_EVENT_ACTION_DOWN;
3632 } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
3633 if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
3634 action = AMOTION_EVENT_ACTION_CANCEL;
3635 } else {
3636 action = AMOTION_EVENT_ACTION_UP;
3637 }
3638 } else {
3639 // Can't happen.
3640 ALOG_ASSERT(false);
3641 }
3642 }
。。。。。。。
3650 const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
3651 const int32_t deviceId = getDeviceId();
3652 std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
3653 std::for_each(frames.begin(), frames.end(),
3654 [this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });// 创建了 NotifyMotionArgs 对象,pointerCoords 为对应保存的数据
3655 NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
3656 policyFlags, action, actionButton, flags, metaState, buttonState,
3657 MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
3658 pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
3659 downTime, std::move(frames));
3660 getListener()->notifyMotion(&args);
3661 }
NotifyMotionArgs 重点的参数:
deviceId:设备id
action:up还是什么其他事件 AMOTION_EVENT_ACTION_UP
actionButton: 为0
flags:0
pointerCount:手指的数量
pointerCoords:保存的数据,表示是 xy 坐标,压力值、major等值
xPrecision, yPrecision:与屏幕方向有关
xCursorPosition, yCursorPosition:都是无效的
notifymotion 通知到 InputDispatcher
/frameworks/native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
3601 void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
3602 uint32_t source, int32_t action, int32_t actionButton,
3603 int32_t flags, int32_t metaState, int32_t buttonState,
3604 int32_t edgeFlags, const PointerProperties* properties,
3605 const PointerCoords* coords, const uint32_t* idToIndex,
3606 BitSet32 idBits, int32_t changedId, float xPrecision,
3607 float yPrecision, nsecs_t downTime) {
3608 PointerCoords pointerCoords[MAX_POINTERS];
3609 PointerProperties pointerProperties[MAX_POINTERS];
3610 uint32_t pointerCount = 0;
3611 while (!idBits.isEmpty()) {
3612 uint32_t id = idBits.clearFirstMarkedBit();
3613 uint32_t index = idToIndex[id];
3614 pointerProperties[pointerCount].copyFrom(properties[index]);
3615 pointerCoords[pointerCount].copyFrom(coords[index]);
3616
3617 if (changedId >= 0 && id == uint32_t(changedId)) {
3618 action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
3619 }
3620
3621 pointerCount += 1;
3622 }
3623
3624 ALOG_ASSERT(pointerCount != 0);
3625 // 如果是单指的话,则会将AMOTION_EVENT_ACTION_POINTER_UP设置为 AMOTION_EVENT_ACTION_UP
3626 if (changedId >= 0 && pointerCount == 1) {
3627 // Replace initial down and final up action.
3628 // We can compare the action without masking off the changed pointer index
3629 // because we know the index is 0.
3630 if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
3631 action = AMOTION_EVENT_ACTION_DOWN;
3632 } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
3633 if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
3634 action = AMOTION_EVENT_ACTION_CANCEL;
3635 } else {
3636 action = AMOTION_EVENT_ACTION_UP;
3637 }
3638 } else {
3639 // Can't happen.
3640 ALOG_ASSERT(false);
3641 }
3642 }
3643 float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
3644 float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
3645 if (mDeviceMode == DeviceMode::POINTER) {
3646 auto [x, y] = getMouseCursorPosition();
3647 xCursorPosition = x;
3648 yCursorPosition = y;
3649 }
3650 const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
3651 const int32_t deviceId = getDeviceId();
3652 std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
3653 std::for_each(frames.begin(), frames.end(),
3654 [this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });// 将所有的参数封装为 NotifyMotionArgs
3655 NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
3656 policyFlags, action, actionButton, flags, metaState, buttonState,
3657 MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
3658 pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
3659 downTime, std::move(frames));// getListener 去通知到观察者
3660 getListener()->notifyMotion(&args);
3661 }
getListener 的实现为:
/frameworks/native/services/inputflinger/reader/mapper/InputMapper.h
TouchInputMapper 类继承了 InputMapper
// 这里获取到context,通过 mDeviceContext.getContext()
49 inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }// 通过ceontext 获取到 Listener
51 inline InputListenerInterface* getListener() { return getContext()->getListener(); }
mDeviceContext 是在初始化 传入的
/frameworks/native/services/inputflinger/reader/InputDevice.cpp
143 void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
144 if (mDevices.find(eventHubId) != mDevices.end()) {
145 return;
146 }
147 std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));。。。。
204 // Touchscreens and touchpad devices.
205 if (classes.test(InputDeviceClass::TOUCH_MT)) {// contextPtr 是 InputDeviceContext 对象
206 mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
所以 mDeviceContext 是 InputDeviceContext,再调用其 getContext 方法
/frameworks/native/services/inputflinger/reader/include/InputDevice.h
239 class InputDeviceContext {
240 public:
241 InputDeviceContext(InputDevice& device, int32_t eventHubId);
242 ~InputDeviceContext();
243
244 inline InputReaderContext* getContext() { return mContext; }========
600 InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
601 : mDevice(device),// 为构造函数中传入的,即通过 InputDevice.getContext 获取
602 mContext(device.getContext()),
603 mEventHub(device.getContext()->getEventHub()),
604 mId(eventHubId),
// 为构造函数中传入的,即通过 InputDevice.getContext 获取
也是再 InputDevice 中传入的
44 class InputDevice {
45 public:
46 InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
47 const InputDeviceIdentifier& identifier);
48 ~InputDevice();
49
50 inline InputReaderContext* getContext() { return mContext; }
mContext 为内部的类为 ContextImpl
/frameworks/native/services/inputflinger/reader/include/InputReader.h
124 class ContextImpl : public InputReaderContext {
125 InputReader* mReader;
126 IdGenerator mIdGenerator;
127
128 public:
129 explicit ContextImpl(InputReader* reader);
130 // lock is already held by the input loop
131 void updateGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override;
132 int32_t getGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override;
133 void disableVirtualKeysUntil(nsecs_t time) REQUIRES(mReader->mLock) override;
134 bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode)
135 REQUIRES(mReader->mLock) override;
136 void fadePointer() REQUIRES(mReader->mLock) override;
137 std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId)
138 REQUIRES(mReader->mLock) override;
139 void requestTimeoutAtTime(nsecs_t when) REQUIRES(mReader->mLock) override;
140 int32_t bumpGeneration() NO_THREAD_SAFETY_ANALYSIS override;
141 void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices)
142 REQUIRES(mReader->mLock) override;
143 void dispatchExternalStylusState(const StylusState& outState)
144 REQUIRES(mReader->mLock) override;
145 InputReaderPolicyInterface* getPolicy() REQUIRES(mReader->mLock) override;
146 InputListenerInterface* getListener() REQUIRES(mReader->mLock) override;
147 EventHubInterface* getEventHub() REQUIRES(mReader->mLock) override;
148 int32_t getNextId() NO_THREAD_SAFETY_ANALYSIS override;
149 void updateLedMetaState(int32_t metaState) REQUIRES(mReader->mLock) override;
150 int32_t getLedMetaState() REQUIRES(mReader->mLock) REQUIRES(mLock) override;
151 } mContext;
综上:
InputReaderContext* getContext() 返回的对象是 InputReader 的 ContextImpl
接着调用其 listener 的方法:
/frameworks/native/services/inputflinger/reader/InputReader.cpp
948 InputListenerInterface* InputReader::ContextImpl::getListener() {
// 获取到的是 对象
949 return mReader->mQueuedListener.get();
950 }======
43 InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
44 const sp<InputReaderPolicyInterface>& policy,
// listener 传入的参数是 InputDispatcher
45 const sp<InputListenerInterface>& listener)
46 : mContext(this),
47 mEventHub(eventHub),
48 mPolicy(policy),
49 mGlobalMetaState(0),
50 mLedMetaState(AMETA_NUM_LOCK_ON),
51 mGeneration(1),
52 mNextInputDeviceId(END_RESERVED_ID),
53 mDisableVirtualKeysTimeout(LLONG_MIN),
54 mNextTimeout(LLONG_MAX),
55 mConfigurationChangesToRefresh(0) {
56 mQueuedListener = new QueuedInputListener(listener);
所以是调用到 QueuedInputListener 的方法 notifyMotion
/frameworks/native/services/inputflinger/InputListener.cpp
315 QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
316 mInnerListener(innerListener) {
317 }337 void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
338 traceEvent(__func__, args->id);// 创建 NotifyMotionArgs 对象包装 args,将其保存到参数队列中
339 mArgsQueue.push_back(new NotifyMotionArgs(*args));
340 }========
// 最后需要调用flush,去统一派发
367 void QueuedInputListener::flush() {
368 size_t count = mArgsQueue.size();
369 for (size_t i = 0; i < count; i++) {
370 NotifyArgs* args = mArgsQueue[i];
371 args->notify(mInnerListener);
372 delete args;
373 }
374 mArgsQueue.clear();
375 }=======
// 然后调用观察者 InputDispatcher 去通知触摸事件 notifyMotion
191 void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
192 listener->notifyMotion(this);
193 }
// 3)观察者队列去flush,处理全部的事件:flush
调用观察者 InputDispatcher 去通知触摸事件 notifyMotion
/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
3817 void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3818 #if DEBUG_INBOUND_EVENT_DETAILS// 会打印对应的log
3819 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3820 "displayId=%" PRId32 ", policyFlags=0x%x, "
3821 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3822 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3823 "yCursorPosition=%f, downTime=%" PRId64,
3824 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3825 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3826 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3827 args->xCursorPosition, args->yCursorPosition, args->downTime);
3828 for (uint32_t i = 0; i < args->pointerCount; i++) {
3829 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3830 "x=%f, y=%f, pressure=%f, size=%f, "
3831 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3832 "orientation=%f",
3833 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3834 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3835 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3836 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3837 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3838 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3839 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3840 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3841 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3842 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3843 }。。。。。
3885 // Just enqueue a new motion event.// 将args 封装为 MotionEntry 对象
3886 std::unique_ptr<MotionEntry> newEntry =
3887 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3888 args->source, args->displayId, policyFlags,
3889 args->action, args->actionButton, args->flags,
3890 args->metaState, args->buttonState,
3891 args->classification, args->edgeFlags,
3892 args->xPrecision, args->yPrecision,
3893 args->xCursorPosition, args->yCursorPosition,
3894 args->downTime, args->pointerCount,
3895 args->pointerProperties, args->pointerCoords, 0, 0);
3896 // 将其假如到处理的队列,然后唤醒 inputdispatcher 线程
3897 needWake = enqueueInboundEventLocked(std::move(newEntry));
3898 mLock.unlock();
3899 } // release lock
3900
3901 if (needWake) {
3902 mLooper->wake();
3903 }
3904 }