Android input子系統-(2)

=========================================================

第二部分: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);

...

//進行一些事件和窗口相關的判斷處理

}


分享到:


相關文章: