=========================================================
第二部分:input上報流程_inputReader
=========================================================
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}
||
||
void InputReader::loopOnce()
{
//從EventHub讀取事件,其中EVENT_BUFFER_SIZE = 256 【getEvents在eventHub部分介紹】
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
if (count) {//處理事件【函數定義如下】
processEventsLocked(mEventBuffer, count);
}
mQueuedListener->flush(); //將事件傳到InputDispatcher.
}
||
||
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
//數據事件的處理【函數定義如下】
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);//不會發生
break;
}
}
}
}
||
||
void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
//【函數定義如下】
device->process(rawEvents, count);
}
||
||
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
//調用具體mapper來處理
mapper->process(rawEvent);
}
}
||
||//【本文以觸屏為例】
void TouchInputMapper::process(const RawEvent* rawEvent) {
mCursorButtonAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
//【函數定義如下】
sync(rawEvent->when);
}
}
||
||
void TouchInputMapper::sync(nsecs_t when) {
//【函數定義如下】
processRawTouches(false);
}
||
||
void TouchInputMapper::processRawTouches(bool timeout) {
for(count = 0; count < N; count++) {
// All ready to go.
clearStylusDataPendingFlags();
mCurrentRawState.copyFrom(next);
if (mCurrentRawState.when < mLastRawState.when) {
mCurrentRawState.when = mLastRawState.when;
}
//【函數定義如下】
cookAndDispatch(mCurrentRawState.when);
}
}
||
||
void TouchInputMapper::cookAndDispatch(nsecs_t when) {
// Cook pointer data. This call populates the mCurrentCookedState.cookedPointerData structure
// with cooked pointer data that has the same ids and indices as the raw data.
// The following code can use either the raw or cooked data, as needed.
cookPointerData();
// Apply stylus pressure to current cooked state.
applyExternalStylusTouchState(when);
// Synthesize key down from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
// Dispatch the touches either directly or by translation through a pointer on screen.
if (mDeviceMode == DEVICE_MODE_POINTER) {
// Stylus takes precedence over all tools, then mouse, then finger.
PointerUsage pointerUsage = mPointerUsage;
dispatchPointerUsage(when, policyFlags, pointerUsage);
} else {
if (!mCurrentMotionAborted) {
//【函數定義如下】
dispatchTouches(when, policyFlags);
}
}
// Synthesize key up from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
// Copy current touch to last touch in preparation for the next cycle.
mLastRawState.copyFrom(mCurrentRawState);
mLastCookedState.copyFrom(mCurrentCookedState);
}
||
||
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
//【函數定義如下】
dispatchMotion();
}
||
||
void TouchInputMapper::dispatchMotion() {
getListener()->notifyMotion(&args);
}
||
||
void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
//將input事件封裝之後,將其加入到一個ArgsQueue隊列
mArgsQueue.push(new NotifyMotionArgs(*args));
}
/*
InputReader的loopOnce過程, 可知當執行完processEventsLocked()過程,
然後便開始執行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();
}
||
||
void NotifyMotionArgs::notify(const sp<inputlistenerinterface>& listener) const {/<inputlistenerinterface>
listener->notifyMotion(this);
}
||
||
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
//構造MotionEntry,然後將其加入到enqueueInboundEventLocked之中
MotionEntry* newEntry = new MotionEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
args->action, args->actionButton, 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);
if (needWake) {
mLooper->wake();//喚醒其中的looper
}
}
||
||
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry);
...
//進行一些事件和窗口相關的判斷處理
}
閱讀更多 AIOT小學生 的文章