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