参考学习链接:
https://www.jianshu.com/p/34f5c7d55337
https://www.jianshu.com/p/d22d86cb04c7
路径:./frameworks/native/services/inputflinger/EventHub.cpp
Eventhub利用方法getEvent获取input/event事件
Eventhub:
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
}
路径:./nativer/services/inputflinger/InputReader.cpp
getEvent被调用的地方如下流程:
InputReaderThread::threadLoop()---> InputReader::loopOnce()--->
EventHub::getEvents()---> InputReader::processEventsLocked()//处理event事件
//InputReader::processEventsLocked处理事件有如下四种类型:
//原始输入事件(触摸按键等均为原始输入事件)
(1)(type < EventHubInterface::FIRST_SYNTHETIC_EVENT):
InputReader::processEventsForDeviceLocked
//设备加载
(2)EventHubInterface::DEVICE_ADDED:
addDeviceLocked
//设备卸载
(3) EventHubInterface::DEVICE_REMOVED:
removeDeviceLocked
//设备扫描完成
(4)EventHubInterface::FINISHED_DEVICE_SCAN:
handleConfigurationChangedLocked
//触摸按键等均为原始输入事件,因此执行的是processEventsForDeviceLocked()
processEventsForDeviceLocked()--->InputDevice::process()--->
InputDevice::process(){
......
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
mapper->process(rawEvent);
}
......
}
最终InputMapper::process()//最终通过inputMapper来继续上报
mMappers是通过addMapper初始化的
void InputDevice::addMapper(InputMapper* mapper) {
mMappers.add(mapper);
}
InputMapper::process()处理过程
InputMapper有多个子类:如下
(1)SwitchInputMapper
(2)VibratorInputMapper
(3)KeyboardInputMapper //键盘输入
(4)CursorInputMapper
(5)MultiTouchInputMapper //多点触摸
(6)SingleTouchInputMapper //单点触摸
(7)JoystickInputMapper
这里以SingleTouchInputMapper为映射路径跟踪
SingleTouchInputMapper::process()
void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
TouchInputMapper::process(rawEvent);
mSingleTouchMotionAccumulator.process(rawEvent);
}
(1)获取按键坐标:
void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_ABS) {
switch (rawEvent->code) {
case ABS_X:
mAbsX = rawEvent->value;
break;
case ABS_Y:
mAbsY = rawEvent->value;
break;
case ABS_PRESSURE:
mAbsPressure = rawEvent->value;
break;
case ABS_TOOL_WIDTH:
mAbsToolWidth = rawEvent->value;
break;
case ABS_DISTANCE:
mAbsDistance = rawEvent->value;
break;
case ABS_TILT_X:
mAbsTiltX = rawEvent->value;
break;
case ABS_TILT_Y:
mAbsTiltY = rawEvent->value;
break;
}
}
}
void TouchInputMapper::process(const RawEvent* rawEvent) {
ALOGE("--touch inputmapper::process--");
mCursorButtonAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
sync(rawEvent->when);
}//注意这里会同步一次事件
}
同步的流程:
sync(rawEvent->when)--->TouchInputMapper::sync(nsecs_t when)
--->TouchInputMapper::processRawTouches--->TouchInputMapper::cookAndDispatch
--->TouchInputMapper::dispatchTouches--->TouchInputMapper::dispatchMotion()
//这里的dispatchMotion的参数pointerCoords含有坐标信息
dispatchMotion(when, policyFlags, mSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, 0, metaState, buttonState, 0,
mLastCookedState.cookedPointerData.pointerProperties,
mLastCookedState.cookedPointerData.pointerCoords,
mLastCookedState.cookedPointerData.idToIndex,
dispatchedIdBits, upId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
dispatchedIdBits.clearBit(upId);
--->getListener()->notifyMotion(&args)
getListener函数实现:
InputListenerInterface* InputReader::ContextImpl::getListener() {
return mReader->mQueuedListener.get();
}
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener) :
mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mGeneration(1),
mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);//初始化mQueuedListener对象
{
// acquire lock
AutoMutex _l(mLock);
ALOGD("InputReader:: InputReader lock " );
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
} // release lock
ALOGD("InputReader:: InputReader unlock " );
}
因此getListener()->notifyMotion调用的是QueuedInputListener对象的notifyMotion
这里只是将触摸数据打包好一个成一个args,然后添加到参数队列中
void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
mArgsQueue.push(new NotifyMotionArgs(*args));//往mArgsQueue队列添加一个arg信息
}
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();
}
遍历整个mArgsQueue数组, 在input架构中NotifyArgs的实现子类主要有以下几类:
NotifyConfigurationChangedArgs
NotifyKeyArgs
NotifyMotionArgs
NotifySwitchArgs
NotifyDeviceResetArgs
这里以触摸板为例:
路径:services/inputflinger/InputListener.cpp
void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
listener->notifyMotion(this);
}
这里的listener是在InputReader初始化的时候初始化的
路径:services/inputflinger/InputReader.cpp
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener) :
mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mGeneration(1),
mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);//初始化mQueuedListener以及listener对象
{
// acquire lock
AutoMutex _l(mLock);
ALOGD("InputReader:: InputReader lock " );
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
} // release lock
ALOGD("InputReader:: InputReader unlock " );
}
//路径:./services/inputflinger/InputManager.cpp
//初始化InputReader
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
//mDispatcher初始化
//./services/inputflinger/InputManager.cpp:31:
mDispatcher = new InputDispatcher(dispatcherPolicy);
所以 listener->notifyMotion(this);调用的是InputDispatcher对象的notifyMotion
路径:services/inputflinger/InputDispatcher.cpp
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
.....
MotionEvent event;
event.initialize(args->deviceId, args->source, args->action, args->actionButton,
args->flags, args->edgeFlags, args->metaState, args->buttonState,
0, 0, args->xPrecision, args->yPrecision,
args->downTime, args->eventTime,
args->pointerCount, args->pointerProperties, args->pointerCoords);
....
//构造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
}
}
上面的mLooper->wake会唤醒 mLooper->pollOnce(timeoutMillis);//等待超时或者唤醒
--->
bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();
return true;
}
--->
void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LONG_LONG_MAX;
{
// acquire lock
AutoMutex _l(mLock);
mDispatcherIsAliveCondition.broadcast();
// Run a dispatch loop if there are no pending commands.
// The dispatch loop might enqueue commands to run afterwards.
if (!haveCommandsLocked()) {
dispatchOnceInnerLocked(&nextWakeupTime);
}
// Run all pending commands if there are any.
// If any commands were run then force the next poll to wake up immediately.
if (runCommandsLockedInterruptible()) {
nextWakeupTime = LONG_LONG_MIN;
}
} // release lock
// Wait for callback or timeout or wake. (make sure we round up, not down)
nsecs_t currentTime = now();
int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
mLooper->pollOnce(timeoutMillis);//等待超时或者唤醒
}
--->InputDispatcher::dispatchOnceInnerLocked()