Android JB 4.2 中InputManager 分发键盘消息给应用程序的过程分析--2 未完待续。。。。

来源:互联网 发布:mac屏幕不亮logo不亮 编辑:程序博客网 时间:2024/05/20 02:26

Step 1. InputReader.pollOnce

Step 2. EventHub.getEvent

        这两个函数分别定义在InputReader.cpp和EventHub.cpp文件中,前面我们在分析InputManager的启动过程的时,已经看到过这两个函数了。InputReaderThread线程会不民地循环调用InputReader.pollOnce函数来读入键盘事 件,而实际的键盘事件读入操作是由EventHub.getEvent函数来进行的。如果当前没有键盘事件发生,InputReaderThread线程 就会睡眠在EventHub.getEvent函数上,而当键盘事件发生后,就会把这个事件封装成一个RawEvent对象,然后返回到pollOnce 函数中,执行processEventsLocked函数进一步处理:

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {    for (const RawEvent* rawEvent = rawEvents; count;) {        int32_t type = rawEvent->type;        size_t batchSize = 1;        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {            int32_t deviceId = rawEvent->deviceId;            while (batchSize < count) {                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT                        || rawEvent[batchSize].deviceId != deviceId) {                    break;                }                batchSize += 1;            }            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);        } else {            switch (rawEvent->type) {            case EventHubInterface::DEVICE_ADDED:                addDeviceLocked(rawEvent->when, rawEvent->deviceId);                break;            case EventHubInterface::DEVICE_REMOVED:                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);                break;            case EventHubInterface::FINISHED_DEVICE_SCAN:                handleConfigurationChangedLocked(rawEvent->when);                break;            default:                ALOG_ASSERT(false); // can't happen                break;            }        }        count -= batchSize;        rawEvent += batchSize;    }}
在processEventsForDeviceLocked(deviceId, rawEvent, batchSize);处理key事件。

void InputReader::processEventsForDeviceLocked(int32_t deviceId,        const RawEvent* rawEvents, size_t count) {    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);    InputDevice* device = mDevices.valueAt(deviceIndex);    device->process(rawEvents, count);}
首先从rawEvent中取得触发键盘事件设备对象device,然后调用它的process函数进行处理。
void InputDevice::process(const RawEvent* rawEvents, size_t count) {    size_t numMappers = mMappers.size();    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {        if (mDropUntilNextSync) {
        ...        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {          ...        } else {
//处理rawevents            for (size_t i = 0; i < numMappers; i++) {                InputMapper* mapper = mMappers[i];                mapper->process(rawEvent);            }        }    }}

这里的mMapper成员变量保存了一系列输入设备事件处理象,例如负责处理键盘事件的KeyboardKeyMapper对象、负责处理轨迹球事件的 TrackballInputMapper对象以及负责处理触摸屏事件的TouchInputMapper对象, 它们是在InputReader类的成员函数createDevice中创建的。这里查询每一个InputMapper对象是否要对当前发生的事件进行处 理。由于发生的是键盘事件,真正会对该事件进行处理的只有KeyboardKeyMapper对象。

void KeyboardInputMapper::process(const RawEvent* rawEvent) {    switch (rawEvent->type) {    case EV_KEY: {        int32_t scanCode = rawEvent->code;        int32_t usageCode = mCurrentHidUsage;        mCurrentHidUsage = 0; //这个函数首先会检查一下键盘扫描码是否正确,如果正确的话,就会调用processKey函数进一步处理。        if (isKeyboardOrGamepadKey(scanCode)) {            int32_t keyCode;            uint32_t flags;             if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {                keyCode = AKEYCODE_UNKNOWN;                flags = 0;            }            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);        }           break;      }               case EV_MSC: {        if (rawEvent->code == MSC_SCAN) {            mCurrentHidUsage = rawEvent->value;        }        break;      }    case EV_SYN: {        if (rawEvent->code == SYN_REPORT) {            mCurrentHidUsage = 0;        }    }    }}

未完待续。。。。