您的位置:首页 > 移动开发 > Android开发

android inputreader 部分对event数据的处理

2015-10-12 10:20 531 查看
status_t InputManager::start() {

status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);

if (result) {

ALOGE("Could not start InputDispatcher thread due to error %d.", result);

return result;

}

result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);//这里调用了run,但是在framework层没有找到run的方法,所以run应该在别的地方实现的

if (result) {

ALOGE("Could not start InputReader thread due to error %d.", result);

mDispatcherThread->requestExit();

return result;

}

return OK;

}

接着到了

bool InputReaderThread::threadLoop() {

mReader->loopOnce();

return true;

}

void InputReader::loopOnce() {

int32_t oldGeneration;

int32_t timeoutMillis;

bool inputDevicesChanged = false;

Vector<InputDeviceInfo> inputDevices;

{ // acquire lock

AutoMutex _l(mLock);

oldGeneration = mGeneration;

timeoutMillis = -1;

uint32_t changes = mConfigurationChangesToRefresh;

if (changes) {

mConfigurationChangesToRefresh = 0;

timeoutMillis = 0;

refreshConfigurationLocked(changes);

} else if (mNextTimeout != LLONG_MAX) {

nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);

}

} // release lock

size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);//从buffer中获取raw data

{ // acquire lock

AutoMutex _l(mLock);

mReaderIsAliveCondition.broadcast();

if (count) {

processEventsLocked(mEventBuffer, count);//如果是有数据则在这里处理

}

if (mNextTimeout != LLONG_MAX) {

nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

if (now >= mNextTimeout) {

#if DEBUG_RAW_EVENTS

ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);

#endif

mNextTimeout = LLONG_MAX;

timeoutExpiredLocked(now);

}

}

if (oldGeneration != mGeneration) {

inputDevicesChanged = true;

getInputDevicesLocked(inputDevices);

}

} // release lock

// Send out a message that the describes the changed input devices.

if (inputDevicesChanged) {

mPolicy->notifyInputDevicesChanged(inputDevices);

}

mQueuedListener->flush();//会调用监听者(实际上是InputDispatch)来处理掉列队中所有的事件

}

进入

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;

}

#if DEBUG_RAW_EVENTS

ALOGD("BatchSize: %d Count: %d", batchSize, count);

#endif

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;

}

到了

void InputReader::processEventsForDeviceLocked(int32_t deviceId,

const RawEvent* rawEvents, size_t count) {

ssize_t deviceIndex = mDevices.indexOfKey(deviceId);

if (deviceIndex < 0) {

ALOGW("Discarding event for unknown deviceId %d.", deviceId);

return;

}

InputDevice* device = mDevices.valueAt(deviceIndex); //获取相应的device

device->process(rawEvents, count); //调用该device的process函数

}

调用 device->process(rawEvents, count);

void InputDevice::process(const RawEvent* rawEvents, size_t count) {

size_t numMappers = mMappers.size();

for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {

#if DEBUG_RAW_EVENTS

ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",

rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,

rawEvent->when);

#endif

if (mDropUntilNextSync) {

if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {

mDropUntilNextSync = false;

#if DEBUG_RAW_EVENTS

ALOGD("Recovered from input event buffer overrun.");

#endif

} else {

#if DEBUG_RAW_EVENTS

ALOGD("Dropped input event while waiting for next input sync.");

#endif

}

} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {

ALOGI("Detected input event buffer overrun for device %s.", getName().string());

mDropUntilNextSync = true;

reset(rawEvent->when);

} else {

for (size_t i = 0; i < numMappers; i++) {

InputMapper* mapper = mMappers[i];

mapper->process(rawEvent);//调用每个mapper去处理数据

}

}

}

}

void InputDevice::timeoutExpired(nsecs_t when) {

size_t numMappers = mMappers.size();

for (size_t i = 0; i < numMappers; i++) {

InputMapper* mapper = mMappers[i];

mapper->timeoutExpired(when);

}

}

如果是touchmapper

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

TouchInputMapper::process(rawEvent);

mMultiTouchMotionAccumulator.process(rawEvent);

}

在void TouchInputMapper::sync(nsecs_t when) {

......

if (consumeRawTouches(when, policyFlags)) { //如果是virtual key则这边进行处理

mCurrentRawPointerData.clear();

}

......

dispatchTouches(when, policyFlags); //如果是motion则在这边处理

}

consumeRawTouches(when, policyFlags)的目的是将NotifyKeyArgs加入mArgsQueue中

dispatchTouches(when, policyFlags)则是将NotifyMotionArgs加入mArgsQueue中

后面的flush里会调用各自的notify函数也就是notifyMotion或者notifyKey

跟踪mMultiTouchMotionAccumulator.process(rawEvent);

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

if (rawEvent->type == EV_ABS) {

bool newSlot = false;

if (mUsingSlotsProtocol) {

if (rawEvent->code == ABS_MT_SLOT) {

mCurrentSlot = rawEvent->value;

newSlot = true;

}

} else if (mCurrentSlot < 0) {

mCurrentSlot = 0;

}

if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {

#if DEBUG_POINTERS

if (newSlot) {

ALOGW("MultiTouch device emitted invalid slot index %d but it "

"should be between 0 and %d; ignoring this slot.",

mCurrentSlot, mSlotCount - 1);

}

#endif

} else {

Slot* slot = &mSlots[mCurrentSlot];

switch (rawEvent->code) {

case ABS_MT_POSITION_X:

slot->mInUse = true;

slot->mAbsMTPositionX = rawEvent->value;

break;

case ABS_MT_POSITION_Y:

slot->mInUse = true;

slot->mAbsMTPositionY = rawEvent->value;

break;

case ABS_MT_TOUCH_MAJOR:

slot->mInUse = true;

slot->mAbsMTTouchMajor = rawEvent->value;

break;

case ABS_MT_TOUCH_MINOR:

slot->mInUse = true;

slot->mAbsMTTouchMinor = rawEvent->value;

slot->mHaveAbsMTTouchMinor = true;

break;

case ABS_MT_WIDTH_MAJOR:

slot->mInUse = true;

slot->mAbsMTWidthMajor = rawEvent->value;

break;

case ABS_MT_WIDTH_MINOR:

slot->mInUse = true;

slot->mAbsMTWidthMinor = rawEvent->value;

slot->mHaveAbsMTWidthMinor = true;

break;

case ABS_MT_ORIENTATION:

slot->mInUse = true;

slot->mAbsMTOrientation = rawEvent->value;

break;

case ABS_MT_TRACKING_ID:

if (mUsingSlotsProtocol && rawEvent->value < 0) {

// The slot is no longer in use but it retains its previous contents,

// which may be reused for subsequent touches.

slot->mInUse = false;

} else {

slot->mInUse = true;

slot->mAbsMTTrackingId = rawEvent->value;

}

break;

case ABS_MT_PRESSURE:

slot->mInUse = true;

slot->mAbsMTPressure = rawEvent->value;

break;

case ABS_MT_DISTANCE:

slot->mInUse = true;

slot->mAbsMTDistance = rawEvent->value;

break;

case ABS_MT_TOOL_TYPE:

slot->mInUse = true;

slot->mAbsMTToolType = rawEvent->value;

slot->mHaveAbsMTToolType = true;

break;

} //完成填充slot

}

} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {

// MultiTouch Sync: The driver has returned all data for *one* of the pointers.

mCurrentSlot += 1;

}

}

这边填充完mslots数组之后,这个数组会在sync函数中被使用

void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {

RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];

//通过outpointer把数据从之前的mslots数组中取出放入mCurrentRawPointerData.pointers[];

}

void TouchInputMapper::sync(nsecs_t when) {

const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);

//通过这个pointer读取mCurrentRawPointerData的数据来标记一些标志位方便构造一个args对象

}

回头看 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();

}

InputReader拥有一个EventHub对象,但这个对象不是它创建的,而是在创建InputReader时作为参数传入的。所以inputreader会共享eventhub的buffer
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: