• 2-(13/24)_输入系统_输入系统_Dispatcher线程_分发dispatch


    2-(13/24)_输入系统_输入系统_Dispatcher线程_分发dispatch

    前言

    根据说的找答案:
    数据到dispatch后需要将按键数据上传至app。
    如何上传呢?
    1、先把事件放至队列中。 outboundQueue队列中
    2、查找目标app,得到conection。
    3、放入它的outboundQueue。

    1、dpspatch线程中有一鼐vector mconnectionByFd 里面放有一个个的 connection。
    2、每一个connection对应于一个个应用程序。
    3、connection中含有 inputchannel,inputchannel数据结构中有fd。
    4、App中也有一个fd
    5、两者的fd来源于socketpair,两边可以通过此fd来通信。

    用文字来描述分发过程.
    1、查找目标。向WindowManagerService查询当前window,获得对应的connection。
    2、把输入事件放入connection的队列。
    3、从队列中逐个把事件写入fd

    1. dispatchKeyLocked//InputDispatcher.cpp 从这里开始分发
    2. int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,entry, inputTargets, nextWakeupTime);//查找目标窗口
    3. if (mFocusedWindowHandle == NULL)//使用此变量表示目标窗口
    4. addWindowTargetLocked(mFocusedWindowHandle,...,Vector<InputTarget>& inputTargets)
    5. InputTarget& target = inputTargets.editTop();
    6. target.inputChannel = windowInfo->inputChannel;//将windowInfo->inputChannel放至target中
    7. dispatchEventLocked(currentTime, entry, inputTargets);
    8. void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
    9. EventEntry* eventEntry, const Vector<InputTarget>& inputTargets)//inputTargets目标窗口
    10. sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);//取出connection。inputTarget.inputChannel中含有文件句柄,可以根据文件句柄 mconnectionByFd中取出conection
    11. prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);//把输入事件放至connection的队列中。
    12. enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);//放入队列
    13. enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,//根据flag判断是否添加事件
    14. case EventEntry::TYPE_KEY: //按键类事件
    15. connection->outboundQueue.enqueueAtTail(dispatchEntry);//从connection得到队列,将dispatchEntry 放到队列中。dispatchEntry 表示某个输入事件。
    16. InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
    17. ......
    18. startDispatchCycleLocked(currentTime, connection);//把队列中的事件取出写至文件中。
    19. DispatchEntry* dispatchEntry = connection->outboundQueue.head;//取出一个dispatchEntry, outboundQueue队列,中于存放输入事件。
    20. case EventEntry::TYPE_KEY//对于按键类事件使用下用的处理函数
    21. connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
    22. status_t InputPublisher::publishKeyEvent(//InputTransport.cpp
    23. InputMessage msg;
    24. ...//构造msg
    25. mChannel->sendMessage(&msg);//最后发送
    26. nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);//使用sendFd,把数据写到文件句柄中,一旦写入,另一个应用程序可以读出

  • 相关阅读:
    企业私域社群体系化建设技巧分享
    JS-BOM-阶乘计算
    二、进程管理(四)经典同步互斥问题
    降维算法实战项目(2)—使用PCA对图像降维(Python代码+数据集)
    基于springboot框架的快递代取跑腿服务系统
    【NR 定位】3GPP NR Positioning 5G定位标准解读(十)-增强的小区ID定位
    centos 根目录逻辑卷扩容/home -> /
    Spring Tool Suite(STS)初始化配置记录
    c++:C++标准库学习iostream
    Linux设置ssh免密登录
  • 原文地址:https://blog.csdn.net/u010798513/article/details/125559221