Android Framework-Input-3 数据处理

264 阅读18分钟

开局叠甲,可能理解有误,请大佬们斧正。

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.cppvoid 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的构造里构建出来的 传入的 listenerQueuedInputListener 的实现在 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()将数据刷入了mArgsQueueflush() 将调用NotifyMotionArgs.notifyMotion(),删除数据,调用listener 也就是 InputDispatchernotifyMotion()。 在下一步就是进入 InputDispatcher.notifyMotion()。涉及到入队的操作,也就是我们常说的IQ, 数据处理这部分其实在我看来是很繁琐的一套流程,涉及多次结构体的转换,所以我一般对这里的概念就是EventHub 读了dev/input 下的数据,然后经过一套转换,把数据存进了IQ。