inputreader到inputdispacther到channel
来源:互联网 发布:妙趣横生的算法 c 编辑:程序博客网 时间:2024/04/29 04:46
......
oldGeneration=mGeneration;
.....
processEventLocked;
......
nsecs_t now=systemTime(SYSTEM_TIME_MONOTONIC);计算此次运行需要等待的时间if(oldGeneration!=mGeneration)
{
getinputdevicelocked;//获取输入设备
}
......
mpolicy->notifyinputdevicechanged; //输入设备改变通知
.....
//这里的generation之所以可能出现不一样,是因为processEventLocked
的adddevice中要configure device,这个configure中会++mGeneration,所以会出现不同
{
........
}
mQueuedListener->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();
}
看 args->notify(mInnerListener);
执行队列里的notify函数,这个args参数是之前的inputreader里的sync()函数里加入到mArgsQueue里的args;我们先看这个参数mInnerListener,它是关系到Dispatcher和Reader联系的重要桥梁。
QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
mInnerListener(innerListener) {//强制的类型转换
}
在InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener) : //作为参数被导入innerListener
mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mGeneration(1),
mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);
{ // acquire lock
AutoMutex _l(mLock);
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
} // release lock
}
跑到
InputManager::InputManager(
const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);//这个mDispatcher就是上面的const sp<InputListenerInterface>& listener
initialize();
}
再回头看
args->notify()这个函数,文件里有很多类的args,我们以NotifyKeyArgs为例子进行说明
listener->notifyMotion(this);
}调用了listener的notifymotion,这个listener就是inputdispatcher
所以跑到了inputdispatcher的
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
MotionEntry* newEntry = new MotionEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
args->action, args->flags, args->metaState, args->buttonState,
args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
args->displayId,
args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
needWake = enqueueInboundEventLocked(newEntry); //返回值决定是否唤醒dispatcher thread
if (needWake) {
mLooper->wake();
}
}
接着看bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry); //把entry加入mInboundQueue
}
.........
event.initialize(args->deviceId, args->source, args->action,
flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);
KeyEntry* newEntry = new KeyEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
if (needWake) {
mLooper->wake();//执行之前的mDispatcher->dispatchOnce()
}
.......
if (!haveCommandsLocked()) {
dispatchOnceInnerLocked(&nextWakeupTime);
}
.......
mLooper->pollOnce(timeoutMillis);
.......
}
看看dispatchOnceInnerLocked:
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
......
mPendingEvent = mInboundQueue.dequeueAtHead();从之前的mInboundQueue里取出event
case EventEntry::TYPE_KEY: {
ALOGE("matt-case EventEntry::TYPE_KEY");
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
if (isAppSwitchDue) {
if (isAppSwitchKeyEventLocked(typedEntry)) {
resetPendingAppSwitchLocked(true);
isAppSwitchDue = false;
} else if (dropReason == DROP_REASON_NOT_DROPPED) {
dropReason = DROP_REASON_APP_SWITCH;
}
}
if (dropReason == DROP_REASON_NOT_DROPPED
&& isStaleEventLocked(currentTime, typedEntry)) {
dropReason = DROP_REASON_STALE;
}
if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
dropReason = DROP_REASON_BLOCKED;
}
done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
break;
}
......
}
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
............
dispatchEventLocked(currentTime, entry, inputTargets);
............
}
然后
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
............
prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
............
}
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
............
enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
............
}
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);//根据传进来的时间对应的对象eventEntry构造一个DispatchEntry对象,这个对象包括了inputtarget信息,然后把这个对象放到connection对象的outboundQueue里
............
startDispatchCycleLocked(currentTime, connection);//然后把这个对象放到connection对象的outboundQueue里,
接着prepareDispatchCycleLocked函又调用activateConnectionLocked把connection 对象放入mActiveConnections数组,接着又调用startDispatchCycleLocked;在startDispatchCycleLocked函数中首先调用connection对象中的inputPublisher对象的publishKeyEvent函数向客户端通过异步共享内存发布事件,然后调用inputPublisher对象的sendDispatchSignal函数通过管道向客户端发送DispatchSignal信号,告诉客户端由事件到达,触发客户端事件处理流程,到这里就完成了服务端的输入事件处理。
............}
进入
DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset, inputTarget->scaleFactor);
case EventEntry::TYPE_KEY: {
KeyEntry*keyEntry= static_cast<KeyEntry*>(eventEntry);
dispatchEntry->resolvedAction = keyEntry->action;
dispatchEntry->resolvedFlags = keyEntry->flags;
connection->outboundQueue.enqueueAtTail(dispatchEntry); 将数据放入outboundQueue。
traceOutboundQueueLengthLocked(connection);
}
void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
const sp<Connection>& connection, const CancelationOptions& options)
{
.......
case EventEntry::TYPE_KEY:
logOutboundKeyDetailsLocked("cancel - ",
static_cast<KeyEntry*>(cancelationEventEntry));
break;
.......
startDispatchCycleLocked(currentTime, connection);
}
然后到void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection)里的
case EventEntry::TYPE_KEY: {
KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
DispatchEntry* dispatchEntry = connection->outboundQueue.head; //从outboundQueue里取出entry
EventEntry* eventEntry = dispatchEntry->eventEntry;
status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
keyEntry->deviceId, keyEntry->source,
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
keyEntry->keyCode, keyEntry->scanCode,
keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
keyEntry->eventTime);
break;
看看
status_t InputPublisher::publishKeyEvent里有return mChannel->sendMessage(&msg);
- inputreader到inputdispacther到channel
- inputreader是如何将事件传递到inputdispathnotifykey里面去的
- 多个Flume合并一个channel上传文件到Hdfs
- 到
- 这个是最新发布到Channel 9上的示例介绍视频
- 在NIO中如何循环将Channel的数据写到Buffer中??
- Flume 1.7 源码分析(四)从Source写数据到Channel
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之三《加入到Channel》
- Golang从入门到精通(十九):Golang并发编程之Channel
- Channel
- channel
- channel
- Channel
- channel
- Channel
- Channel
- InputReader, CursorInputMapper工作总结
- InputReader和InputDispatcher
- 图片 动画
- 不要滥用UNLOGGED table 和 hash index
- Eclipse创建Maven项目
- 深入理解jQuery.css和jQuery.style源码
- Web service - current time zone for a city?
- inputreader到inputdispacther到channel
- 虚拟机磁盘 centos 扩展空间
- 1.冒泡排序
- JAVA EL表达式详细介绍使用手册
- his系统运维日志----1
- codeforces 551 E. GukiZ and GukiZiana
- __NSCFNumber length
- Android 将asserts文件夹内文件写入SD卡中
- 系统负载