Android 2.3 input输入事件处理(2)

2、数据处理流程:

Eventhub 从设备/dev/input/eventX中读取数据:

bool EventHub::getEvent(RawEvent* outEvent)
{

int pollResult = poll(mFDs, mFDCount, -1);

if (pfd.revents & POLLIN) {
                int32_t readSize = read(pfd.fd, mInputBufferData,
                        sizeof(struct input_event) * INPUT_BUFFER_SIZE);


...

}

InputReader 根据mapper处理不同的数据,这里有SwitchInputMapper、KeyboardInputMapper,TrackballInputMapper,TouchInputMapper,MouseInputMapper 等处理mapper过滤数据

void InputReader::loopOnce() {
     RawEvent rawEvent;
     mEventHub->getEvent(& rawEvent);

process(& rawEvent);
}


void InputReader::process(const RawEvent* rawEvent) {

switch (rawEvent->type) {
    case EventHubInterface::DEVICE_ADDED:
        addDevice(rawEvent->deviceId);
        break;


    case EventHubInterface::DEVICE_REMOVED:
        removeDevice(rawEvent->deviceId);
        break;


    case EventHubInterface::FINISHED_DEVICE_SCAN:
        handleConfigurationChanged(rawEvent->when);
        break;


    default:
        consumeEvent(rawEvent);
        break;
    }
}


分别通过:

virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
            uint32_t policyFlags, int32_t action, int32_t flags,
            int32_t metaState, int32_t edgeFlags,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
    virtual void notifySwitch(nsecs_t when,
            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;


将数据回调给inputDisplatcher模块

InputDispatcher 对于接收到的数据进行分发:
InputDispatcherThread线程的轮询过程dispatchOnce()-->dispatchOnceInnerLocked(), InputDispatcherThread线程不停的执行该操作,以达到轮询的目的。

处理进行分发给不同的应用
bool InputDispatcherThread::threadLoop() {
dispatchOnceInnerLocked{
case EventEntry::TYPE_KEY:
dispatchKeyLocked(); --> dispatchEventToCurrentInputTargetsLocked
--> prepareDispatchCycleLocked
case EventEntry::TYPE_MOTION:
dispatchMotionLocked();
}
}

dispatchKeyLocked函数,它接下来就调用dispatchEventToCurrentInputTargetsLocked来进一步处理了。把当前需要接受键盘事件的Activity窗口添加到mCurrentInputTargets中去了,因此,这里就分别把它们取出来,然后调用prepareDispatchCycleLocked函数把键盘事件分发给它们处理。


inputDispatcherThread处理流程:
inputDispatcherThread的主要操作是分两块同时进行的,

一部分是对InputReader传递过来的事件进行dispatch前处理,比如确定focus window,特殊按键处理如HOME/ENDCALL等,在预处理完成 后,InputDispatcher会将事件存储到对应的focus window的outBoundQueue,这个outBoundQueue队列是InputDispatcher::Connection的成员函数,因此它是和ViewRoot相关的。

一部分是对looper的轮询,这个轮询过程是检查NativeInputQueue是否处理完成上一个事件,如果NativeInputQueue处理完成事件,它就会向通过管道向InputDispatcher发送消息指示consume完成,只有NativeInputQueue consume完成一个事件,InputDispatcher才会向共享内存写入另一个事件。

这里主要用到了两个Queue队列:

Queue<DispatchEntry> outboundQueue; 利用handleReceiveCallback 处理收到的数据

利用inputPublisher中的publishKeyEvent及publishMotionEvent将event写入到共享内存中。

Queue<EventEntry> mInboundQueue; 处理notify回调来的数据

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyjxjp.html