• 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,把数据写到文件句柄中,一旦写入,另一个应用程序可以读出

  • 相关阅读:
    C++基础从0到1入门编程(二)
    Uniapp入门
    Keil5----打开map文件方法和map文件解析
    用Python实现链式调用
    MySQL高级篇之索引结构
    linux命令grep
    认识Unity中的音效
    经纬度坐标为中心点生成米距离长度半径的圆形面,含java js源码+在线绘制,代码简单零依赖
    P1347 排序(拓扑 + spfa判断环 or 拓扑[内判断环])
    在vue项目中使用electron
  • 原文地址:https://blog.csdn.net/u010798513/article/details/125559221