1 InputManagerService简介
InputManagerService(IMS)创建过程和其他服务类似,都由SystemServer启动,java层的IMS实际上是对native层NativeInputManager的包装。nativeInit函数中通过jni创建NativeInputManager对象,在NativeInputManager中创建了EventHub和InputManager对象,IMS在native层的实现主体是EventHub和InputManager。
inputManager = new InputManagerService(context);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
// step1, 开启事件接收和派发线程
inputManager.start();
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
// step2, 构造natvie InputManager对象
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
LocalServices.addService(InputManagerInternal.class, new LocalService());
}
1.1 com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
1.2 NativeInputManager
- EventHub:
监听/dev/input/下的设备节点,监听输入事件的上报,输入设备的插拔.如果有事件处理,则交给InputReader处理 - InputReaderThread线程:
EventHub监听/dev/input/下的设备节点,监听输入事件的上报,输入设备的插拔.前期处理后,将事件投放到mInboundQueue队列中交给InputDispatcherThread处理 - InputDispatcherThread线程:
从mInboundQueue队列中取出事件,通过findFocusedWindowTargetsLocked和findTouchedWindowTargetsLocked找到对应接收事件的窗口,将事件放入到接收窗口中的outboundQueue,当派发事件时,从outboundQueue队列中移除,将事件添加到waitQueue队列, 事件处理完成,则将事件从waitQueue队列中删除,事件处理完成,发送下一个事件
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
sp<EventHub> eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
}
1.3 InputManager
InputManager中创建了2个两个线程InputReaderThread和InputDispatcherThread。
InputManager::InputManager(
const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
// step1, 把mDispatcher传给了InputReader,InputDispatcher实现了InputListenerInterface接口
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
// step2, 初始化线程对象
initialize();
}
void InputManager::initialize() {
// 创建线程对象
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
1.4 启动线程
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
status_t InputManager::start() {
// 启动线程
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
return OK;
}
2 InputReader分析
InputReader线程循环调用loopOnce函数,通过EventHub的getEvents函数不断获取系统中的输入事件,前期的加工处理(将对应的机器码映射成对应的keycode),然后添加到QueuedInputListener的mArgsQueue队列中,然后通过QueuedInputListener的flush函数逐一存放到mInboundQueue队列中
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) {
// listener为InputDispatcher对象
mQueuedListener = new QueuedInputListener(listener);
}
2.1 InputReader::loopOnce
void InputReader::loopOnce() {
// step1, 获取输入事件
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{ // acquire lock
AutoMutex _l(mLock);
if (count) {
// step2, 处理输入事件
processEventsLocked(mEventBuffer, count);
}
} // release lock
// step3, 将输入事件交给InputDispatcher处理
mQueuedListener->flush();
}
2.2 InputReader::processEventsLocked
processEventsLocked主要功能为输入事件的前期处理和输入设备的插拔处理,我们主要分析输入事件的处理
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
int32_t deviceId = rawEvent->deviceId;
// 输入事件的处理
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;
default:
ALOG_ASSERT(false); // can't happen
break;
}
}
count -= batchSize;
rawEvent += batchSize;
}
}
2.3 InputReader::processEventsForDeviceLocked
直接调用InputDevice的process函数,InputDevice中有个InputMapper类型的mMappers数组,根据输入设备的不同,map不一样,process最终调用对应的InputMapper的process函数
常见的InputMapper类型
// 按键事件相关
KeyboardInputMapper
// 触摸事件相关
MultiTouchInputMapper
void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
InputDevice* device = mDevices.valueAt(deviceIndex);
if (device->isIgnored()) {
//ALOGD("Discarding event for ignored deviceId %d.", deviceId);
return;
}
// 调用InputDevice的process函数
device->process(rawEvents, count);
}
2.4 InputDevice::process
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
size_t numMappers = mMappers.size();
for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
// 调用对应mapper的process函数
mapper->process(rawEvent);
}
}
}
2.5 KeyboardInputMapper
接下来以KeyboardInputMapper来分析,和其他InputMapper处理流程相似
process函数中发现真正处理事件的函数为processKey,接下来继续分析processKey函数,构造NotifyKeyArgs对象,调用getListener()->notifyKey(&args), 其中getListener()为QueuedInputListener, 分析QueuedInputListener的notifyKey函数发现,将NotifyKeyArgs添加到QueuedInputListener的mArgsQueue队列中,后续通过flush函数将事件传递给InputDispatcher处理
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY: {
int32_t scanCode = rawEvent->code;
int32_t usageCode = mCurrentHidUsage;
mCurrentHidUsage = 0;
if (isKeyboardOrGamepadKey(scanCode)) {
processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
}
break;
}
}
}
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,
int32_t usageCode) {
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
// getListener为QueuedInputListener
getListener()->notifyKey(&args);
}
void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
mArgsQueue.push(new NotifyKeyArgs(*args));
}
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
// 调用NotifyArgs的notify函数
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
// listener为InputDispatcher
listener->notifyKey(this);
}
2.6 InputDispatcher::notifyKey
调用PhoneWindowManager的interceptKeyBeforeQueueing或interceptMotionBeforeQueueing函数,判断是否需要将此按键事件或者触摸事件进行拦截,如果不需要拦截,则将事件添加到mInboundQueue中, 供InputDispatcher使用。
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
// step1, 调用PhoneWindowManager的interceptKeyBeforeQueueing函数,是否需要将此事件拦截
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
bool needWake;
{ // acquire lock
mLock.lock();
int32_t repeatCount = 0;
KeyEntry* newEntry = new KeyEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
// step2, 将KeyEntry入mInboundQueue队列
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
} // release lock
// step3, 是否需要唤醒InputDispatcher线程
if (needWake) {
mLooper->wake();
}
}
2.7 InputDispatcher::notifyMotion
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
// step1, 调用PhoneWindowManager的interceptMotionBeforeQueueing函数,是否需要将此事件拦截
mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
bool needWake;
{ // acquire lock
mLock.lock();
// Just enqueue a new motion event.
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);
// step2, 将MotionEntry入mInboundQueue队列
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
} // release lock
// step3, 是否需要唤醒InputDispatcher线程
if (needWake) {
mLooper->wake();
}
}
2.8 InputDispatcher::enqueueInboundEventLocked
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
// 将事件添加到mInboundQueue队列,供InputDispatcher使用
mInboundQueue.enqueueAtTail(entry);
}
2.9 InputReader处理事件流程:
1 loopOnce
2 mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
2 processEventsLocked
3 processEventsForDeviceLocked
4 device->process(rawEvents, count);
5 mapper->process(rawEvent);
6 processKey
7 getListener()->notifyKey(&args);
2 mQueuedListener->flush();
3 args->notify(mInnerListener);
4 listener->notifyKey(this);
5 interceptKeyBeforeQueueing
5 enqueueInboundEventLocked
3 InputDispatcher分析
threadLoop函数中循环调用dispatchOnce,haveCommandsLocked函数根据mCommandQueue队列中是否存在事件队列,如果没有事件处理,则准备处理下一个事件,接着调用dispatchOnceInnerLocked做接下来的动作
void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LONG_LONG_MAX;
{ // acquire lock
// Run a dispatch loop if there are no pending commands.
// The dispatch loop might enqueue commands to run afterwards.
// 判断mCommandQueue中是否有事件正在派发
if (!haveCommandsLocked()) {
// 准备处理下一个事件
dispatchOnceInnerLocked(&nextWakeupTime);
}
} // release lock
}
3.1 InputDispatcher::dispatchOnceInnerLocked
dispatchOnceInnerLocked函数根据输入事件的类型不同走不同的流程,按键事件和输入事件派发的流程大致相同,我们以按键事件流程来分析,
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
switch (mPendingEvent->type) {
case EventEntry::TYPE_KEY: {
// step1, 按键事件处理
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
break;
}
case EventEntry::TYPE_MOTION: {
// step2, 触摸事件处理
MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
done = dispatchMotionLocked(currentTime, typedEntry,
&dropReason, nextWakeupTime);
break;
}
}
// 处理完的收尾工作
if (done) {
mLastDropReason = dropReason;
releasePendingEventLocked();
}
}
3.2 InputDispatcher::dispatchKeyLocked
KeyEntry第一次进来没有被处理时,entry->interceptKeyResult为KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN,首先调用InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible函数,内部会调用PhoneWindowManager的interceptKeyBeforeDispatching来判断此事件是否需要拦截,不拦截则继续处理。findFocusedWindowTargetsLocked函数找到接收输入事件的窗口,保存在inputTargets中, dispatchEventLocked函数做后续的处理
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Preprocessing.
// Give the policy a chance to intercept the key.
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
// step1, 调用PhoneWindowManager的interceptKeyBeforeDispatching来判断此事件是否需要拦截
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
if (mFocusedWindowHandle != NULL) {
commandEntry->inputWindowHandle = mFocusedWindowHandle;
}
commandEntry->keyEntry = entry;
entry->refCount += 1;
// step2, 直接返回,等待postCommandLocked队列处理完
return false; // wait for the command to run
} else {
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
}
} else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
if (*dropReason == DROP_REASON_NOT_DROPPED) {
*dropReason = DROP_REASON_POLICY;
}
}
// step3, 如果放弃事件,则不往下处理
if (*dropReason != DROP_REASON_NOT_DROPPED) {
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true;
}
// step4,找到对应接收事件的inputTargets
Vector<InputTarget> inputTargets;
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
// step5, 派发事件
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
3.3 InputDispatcher::dispatchEventLocked
getConnectionIndexLocked获取输入窗口对应的socket连接,稍后我们再来分析App窗口是如何和IMS之间建立连接的,connectionIndex大于0说明存在对应的连接通道,接着调用了prepareDispatchCycleLocked函数。
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
for (size_t i = 0; i < inputTargets.size(); i++) {
const InputTarget& inputTarget = inputTargets.itemAt(i);
ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
}
}
}
3.4 InputDispatcher::prepareDispatchCycleLocked
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
// Not splitting. Enqueue dispatch entries for the event as is.
// 将输入事件放入outboundQueue队列中
enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
}
3.5 InputDispatcher::enqueueDispatchEntriesLocked
根据InputTarget类型,确定事件是否添加到到outboundQueue中,如果outboundQueue不为空,则调用startDispatchCycleLocked将事件信息派发给对应的app窗口,等待app发送处理结束的消息
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
bool wasEmpty = connection->outboundQueue.isEmpty();
// Enqueue dispatch entries for the requested modes.
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_IS);
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
// If the outbound queue was previously empty, start the dispatch cycle going.
// 如果outboundQueue有数据,派发
if (wasEmpty && !connection->outboundQueue.isEmpty()) {
startDispatchCycleLocked(currentTime, connection);
}
}
3.6 InputDispatcher::startDispatchCycleLocked
通过connection->inputPublisher的publishKeyEvent或者publishMotionEvent派发给指定app窗口,最终会回调ViewRootImpl中内部类WindowInputEventReceiver中的onInputEvent函数,App中的事件流程暂时不分析。然后将派发的事件从outboundQueue队列中移除,添加到waitQueue队列中,如果app事件处理完成,会回调InputDispatcher的handleReceiveCallback函数,将事件从waitQueue中移除,事件处理结束,接着派发下一个事件
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection) {
while (connection->status == Connection::STATUS_NORMAL
&& !connection->outboundQueue.isEmpty()) {
DispatchEntry* dispatchEntry = connection->outboundQueue.head;
dispatchEntry->deliveryTime = currentTime;
// Publish the event.
status_t status;
EventEntry* eventEntry = dispatchEntry->eventEntry;
switch (eventEntry->type) {
case EventEntry::TYPE_KEY: {
KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
// Publish the key event.
// step1, 将按键事件发送到app窗口
status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
keyEntry->deviceId, keyEntry->source,
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
keyEntry->keyCode, keyEntry->scanCode,
keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
keyEntry->eventTime);
break;
}
case EventEntry::TYPE_MOTION: {
MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
// Publish the motion event.
// step2, 将触摸事件发送到app窗口
status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
motionEntry->deviceId, motionEntry->source,
dispatchEntry->resolvedAction, motionEntry->actionButton,
dispatchEntry->resolvedFlags, motionEntry->edgeFlags,
motionEntry->metaState, motionEntry->buttonState,
xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
motionEntry->downTime, motionEntry->eventTime,
motionEntry->pointerCount, motionEntry->pointerProperties,
usingCoords);
break;
}
}
// Re-enqueue the event on the wait queue.
// step3, 从outboundQueue从移除
connection->outboundQueue.dequeue(dispatchEntry);
traceOutboundQueueLengthLocked(connection);
// step4, 添加到waitQueue队列中
connection->waitQueue.enqueueAtTail(dispatchEntry);
}
}
3.7 InputDispatcher::handleReceiveCallback
handleReceiveCallback当app窗口将事件消费完后,会发一个消息给InputDispatcher, 回调handleReceiveCallback
int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
InputDispatcher* d = static_cast<InputDispatcher*>(data);
{ // acquire lock
std::scoped_lock _l(d->mLock);
bool notify;
sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
if (!(events & ALOOPER_EVENT_INPUT)) {
ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
"events=0x%x", connection->getInputChannelName().c_str(), events);
return 1;
}
nsecs_t currentTime = now();
bool gotOne = false;
status_t status;
for (;;) {
uint32_t seq;
bool handled;
// step1, 接收按键事件处理消息
status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
if (status) {
break;
}
// step2, 事件派发完成相关处理
d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
gotOne = true;
}
if (gotOne) {
d->runCommandsLockedInterruptible();
if (status == WOULD_BLOCK) {
return 1;
}
}
notify = status != DEAD_OBJECT || !connection->monitor;
if (notify) {
ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
connection->getInputChannelName().c_str(), status);
}
}
// Unregister the channel.
d->unregisterInputChannelLocked(connection->inputChannel, notify);
return 0; // remove the callback
} // release lock
}
3.8 InputDispatcher::onDispatchCycleFinishedLocked
onDispatchCycleFinishedLocked里没有做相关处理,最终实现为InputDispatcher::doDispatchCycleFinishedLockedInterruptible,我们来分析doDispatchCycleFinishedLockedInterruptible函数,将DispatchEntry从waitQueue队列中移除事件,将DispatchEntry相关对象析构, 继续派发下一个事件
void InputDispatcher::onDispatchCycleFinishedLocked(
nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
commandEntry->connection = connection;
commandEntry->eventTime = currentTime;
commandEntry->seq = seq;
commandEntry->handled = handled;
}
3.9 InputDispatcher::doDispatchCycleFinishedLockedInterruptible
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
CommandEntry* commandEntry) {
// Handle post-event policy actions.
DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
if (dispatchEntry) {
// Dequeue the event and start the next cycle.
// Note that because the lock might have been released, it is possible that the
// contents of the wait queue to have been drained, so we need to double-check
// a few things.
if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
// step1, 从waitQueue队列中移除事件
connection->waitQueue.dequeue(dispatchEntry);
traceWaitQueueLength(connection);
if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
// step2, 如果当前事件需要重新派发,则继续派发
connection->outboundQueue.enqueueAtHead(dispatchEntry);
traceOutboundQueueLength(connection);
} else {
// step3, 释放事件相关对象
releaseDispatchEntry(dispatchEntry);
}
}
// step4, 派发下一个事件
startDispatchCycleLocked(now(), connection);
}
}
3.10 InputDispatcher发送事件流程:
dispatchOnce
dispatchOnceInnerLocked
dispatchKeyLocked
doInterceptKeyBeforeDispatchingLockedInterruptible
dispatchEventLocked
prepareDispatchCycleLocked
enqueueDispatchEntriesLocked
startDispatchCycleLocked
connection->inputPublisher.publishKeyEvent
3.11 InputDispatcher接收事件处理完成流程:
handleReceiveCallback
connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
finishDispatchCycleLocked
onDispatchCycleFinishedLocked
doDispatchCycleFinishedLockedInterruptible
connection->waitQueue.dequeue(dispatchEntry);
releaseDispatchEntryLocked(dispatchEntry);
4 Activity和IMS之间是如何建立连接的
WindowManagerService是Android中的窗口服务的,负责窗口的添加删除,Activity的添加会调用WMS中的addWindow函数。addWindow函数非常复杂,我们只分析和输入相关连接的建立,InputChannel.openInputChannelPair会创建一个双向的socket, 返回两个InputChannel,使Activity和IMS之间建立联系,然后将窗口相关的信息更新到IMS中,为InputDispatcher正确派发事件到ViewRootImpl提供保障。
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, InputChannel outInputChannel) {
if (outInputChannel != null && (attrs.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
String name = win.makeInputChannelName();
// step1, 创建输入通道
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
win.setInputChannel(inputChannels[0]);
// step2, 将inputChannels[1]传给Activity
inputChannels[1].transferTo(outInputChannel);
// step3, 将将inputChannels[0]传给IMS
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
}
// step4, 更新IMS中的窗口
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
4.1 InputChannel::openInputChannelPair
status_t InputChannel::openInputChannelPair(const String8& name,
sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
int sockets[2];
// 创建socketpair
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
status_t result = -errno;
ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
name.string(), errno);
outServerChannel.clear();
outClientChannel.clear();
return result;
}
int bufferSize = SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
String8 serverChannelName = name;
serverChannelName.append(" (server)");
outServerChannel = new InputChannel(serverChannelName, sockets[0]);
String8 clientChannelName = name;
clientChannelName.append(" (client)");
outClientChannel = new InputChannel(clientChannelName, sockets[1]);
return OK;
}
4.2 com_android_server_input_InputManagerService.cpp
mInputManager.registerInputChannel()函数最终实现为native层中的InputDispatcher::registerInputChannel,创建对应的连接对象,将socket添加到loop中监听,当收到消息,回调InputDispatcher::handleReceiveCallback来处理按键事件的收尾工作
status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
int32_t displayId) {
{ // acquire lock
std::scoped_lock _l(mLock);
// step1, 创建连接通道
sp<Connection> connection = new Connection(inputChannel, false /*monitor*/);
int fd = inputChannel->getFd();
mConnectionsByFd.add(fd, connection);
mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
// step2, 建立回调机制
mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
} // release lock
// Wake the looper because some connections have changed.
mLooper->wake();
return OK;
}
5 总结
Android Activity输入事件分发机制没有分析,请看我的另一篇文章
Android Activity输入事件分发机制