android input 按键分发(inputManager)
来源:互联网 发布:日本直播软件 编辑:程序博客网 时间:2024/05/16 17:01
文章出处:http://blog.csdn.net/shift_wwx/article/details/49764595
请转载的朋友标明出处~~
之前InputManager 的启动过程 已经对inputManager 的启动过程做了简单的介绍。这里先小结一下:
1、InputManagerService 构造,确认DisplayThread,做nativeInit
2、nativeInit ,创建一些实例,例如NativeInputManager、InputManager、EventHub
3、构造InputManager,实例 InputReader、InputDispatcher,并实例 InputReaderThread 对按键进行监控、InputDispatcherThread 对按键进行分发。
对于监控,是根据EventHub来的,这里说一下分发
InputReaderThread线程会不断地循环调用InputReader.loopOnce函数来读入键盘事件,而实际的键盘事件读入操作是由EventHub.getEvent函数来进行的。如果当前没有键盘事件发生,InputReaderThread线程就会睡眠在EventHub.getEvent函数上,而当键盘事件发生后,就会把这个事件封装成一个RawEvent对象,然后返回到loopOnce函数中,执行process函数进一步处理:- processEventsLocked(mEventBuffer, count);
- processEventsForDeviceLocked(deviceId, 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);
- if (device->isIgnored()) {
-
- return;
- }
-
- 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);
- }
- }
- }
- }
这里的mMapper成员变量保存了一系列输入设备事件处理象,例如负责处理键盘事件的KeyboardKeyMapper对象、负责处理轨迹球事件的TrackballInputMapper对象以及负责处理触摸屏事件的TouchInputMapper对象, 它们是在InputReader类的成员函数createDevice中创建的。这里查询每一个InputMapper对象是否要对当前发生的事件进行处理。由于发生的是键盘事件,真正会对该事件进行处理的只有KeyboardKeyMapper对象。- 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)) {
- int32_t keyCode;
- uint32_t flags;
- if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
- keyCode = AKEYCODE_UNKNOWN;
- flags = 0;
- }
- processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
- }
- break;
- }
- case EV_MSC: {
- if (rawEvent->code == MSC_SCAN) {
- mCurrentHidUsage = rawEvent->value;
- }
- break;
- }
- case EV_SYN: {
- if (rawEvent->code == SYN_REPORT) {
- mCurrentHidUsage = 0;
- }
- }
- }
- }
- void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
- int32_t scanCode, uint32_t policyFlags) {
-
- if (down) {
-
- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- keyCode = rotateKeyCode(keyCode, mOrientation);
- }
-
-
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
-
- keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
- } else {
-
- if ((policyFlags & POLICY_FLAG_VIRTUAL)
- && mContext->shouldDropVirtualKey(when,
- getDevice(), keyCode, scanCode)) {
- return;
- }
-
- mKeyDowns.push();
- KeyDown& keyDown = mKeyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
- }
-
- mDownTime = when;
- } else {
-
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
-
- keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
- mKeyDowns.removeAt(size_t(keyDownIndex));
- } else {
-
- ALOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
- return;
- }
- }
-
- int32_t oldMetaState = mMetaState;
- int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
- bool metaStateChanged = oldMetaState != newMetaState;
- if (metaStateChanged) {
- mMetaState = newMetaState;
- updateLedState(false);
- }
-
- nsecs_t downTime = mDownTime;
-
- if (metaStateChanged) {
- getContext()->updateGlobalMetaState();
- }
-
- if (down && !isMetaKey(keyCode)) {
- getContext()->fadePointer();
- }
-
- NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
- down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
- AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
- getListener()->notifyKey(&args);
- }
这个函数首先对按键作一些处理,例如,当某一个DPAD键被按下时,根据当时屏幕方向的不同,它所表示的意义也不同,因此,这里需要根据当时屏幕的方向来调整键盘码:- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- keyCode = rotateKeyCode(keyCode, mOrientation);
- }
如果这个键是一直按着不放的,不管屏幕的方向如何,必须保证后面的键盘码和前面的一样:- ssize_t keyDownIndex = findKeyDown(scanCode);
如果是第一次按下某个键,还必须把它保存在mLocked.keyDowns里面,就是为了处理上面讲的当这个键盘一直按着不放的时候屏幕方向发生改变的情况。如果是松开键盘上的某个键,就把它从mLocked.keyDowns里面删除:- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
-
- keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
- mKeyDowns.removeAt(size_t(keyDownIndex));
- } else {
-
- ALOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
- return;
- }
最后是调用notifyKey:
- getListener()->notifyKey(&args);
---->- InputListenerInterface* InputReader::ContextImpl::getListener() {
- return mReader->mQueuedListener.get();
- }
---->- void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
- mArgsQueue.push(new NotifyKeyArgs(*args));
- }
到这里,我们返回 loopOnce:
-
- if (inputDevicesChanged) {
- mPolicy->notifyInputDevicesChanged(inputDevices);
- }
-
-
-
-
-
-
-
-
- mQueuedListener->flush();
如果input device 发生改变的话,会通过notigyInputDevicesChanged 通知上层。最后会通过mQueuedListener 的flush 激活 InputDispatcher。
通过之前code 看到,processEventsLocked 会将获取的event 以NotifyKeyArgs 的形式存放起来,这里怎么会激活 InputDispatcher呢?
看一下 InputManager 的构造函数:
- InputManager::InputManager(
- const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& readerPolicy,
- const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
- mDispatcher = new InputDispatcher(dispatcherPolicy);
- mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
- initialize();
- }
mReader 的第三个参数就是mDispatcher,再来看看InputReader 的构造:- 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);
-
- {
- AutoMutex _l(mLock);
-
- refreshConfigurationLocked(0);
- updateGlobalMetaStateLocked();
- }
- }
第三个参数传进来是 mDispatcher,到这里就变成了mQueuedListener。所以上面的flush 其实调用的就是 InputDispatcher 的 notifyKey:- void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
- #if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
- "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
- args->eventTime, args->deviceId, args->source, args->policyFlags,
- args->action, args->flags, args->keyCode, args->scanCode,
- args->metaState, args->downTime);
- #endif
- if (!validateKeyEvent(args->action)) {
- return;
- }
-
- uint32_t policyFlags = args->policyFlags;
- int32_t flags = args->flags;
- int32_t metaState = args->metaState;
- if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
- policyFlags |= POLICY_FLAG_VIRTUAL;
- flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- }
- if (policyFlags & POLICY_FLAG_FUNCTION) {
- metaState |= AMETA_FUNCTION_ON;
- }
-
- policyFlags |= POLICY_FLAG_TRUSTED;
-
- int32_t keyCode = args->keyCode;
- if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {
- int32_t newKeyCode = AKEYCODE_UNKNOWN;
- if (keyCode == AKEYCODE_DEL) {
- newKeyCode = AKEYCODE_BACK;
- } else if (keyCode == AKEYCODE_ENTER) {
- newKeyCode = AKEYCODE_HOME;
- }
- if (newKeyCode != AKEYCODE_UNKNOWN) {
- AutoMutex _l(mLock);
- struct KeyReplacement replacement = {keyCode, args->deviceId};
- mReplacedKeys.add(replacement, newKeyCode);
- keyCode = newKeyCode;
- metaState &= ~AMETA_META_ON;
- }
- } else if (args->action == AKEY_EVENT_ACTION_UP) {
-
-
-
- AutoMutex _l(mLock);
- struct KeyReplacement replacement = {keyCode, args->deviceId};
- ssize_t index = mReplacedKeys.indexOfKey(replacement);
- if (index >= 0) {
- keyCode = mReplacedKeys.valueAt(index);
- mReplacedKeys.removeItemsAt(index);
- metaState &= ~AMETA_META_ON;
- }
- }
-
- KeyEvent event;
- event.initialize(args->deviceId, args->source, args->action,
- flags, keyCode, args->scanCode, metaState, 0,
- args->downTime, args->eventTime);
-
- mPolicy->interceptKeyBeforeQueueing(&event, policyFlags);
-
- bool needWake;
- {
- mLock.lock();
-
- if (shouldSendKeyToInputFilterLocked(args)) {
- mLock.unlock();
-
- policyFlags |= POLICY_FLAG_FILTERED;
- if (!mPolicy->filterInputEvent(&event, policyFlags)) {
- return;
- }
-
- 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);
-
- needWake = enqueueInboundEventLocked(newEntry);
- mLock.unlock();
- }
-
- if (needWake) {
- mLooper->wake();
- }
- }
函数首先是调用validateKeyEvent函数来验证action参数是否正确:
- if (!validateKeyEvent(args->action)) {
- return;
- }
- static bool isValidKeyAction(int32_t action) {
- switch (action) {
- case AKEY_EVENT_ACTION_DOWN:
- case AKEY_EVENT_ACTION_UP:
- return true;
- default:
- return false;
- }
- }
正确的action参数的值只能为AKEY_EVENT_ACTION_DOWN(按下)或者AKEY_EVENT_ACTION_UP(松开)。接着是在进queue 之前做一些必须要的操作:
- KeyEvent event;
- event.initialize(args->deviceId, args->source, args->action,
- flags, keyCode, args->scanCode, metaState, 0,
- args->downTime, args->eventTime);
-
- mPolicy->interceptKeyBeforeQueueing(&event, policyFlags)
这个会通过jni 回调到InputManagerService.java 中的接口,也就是InputManager 的启动过程中提到的WindowManagerCallbacks。最后调用enqueueInboundEventLocked函数把这个按键事件封装成一个KeyEntry结构加入到InputDispatcher类的mInboundQueue队列中去:- 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);
-
- needWake = enqueueInboundEventLocked(newEntry);
- bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
- bool needWake = mInboundQueue.isEmpty();
- mInboundQueue.enqueueAtTail(entry);
- traceInboundQueueLengthLocked();
-
- switch (entry->type) {
- case EventEntry::TYPE_KEY: {
-
-
-
- KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
- if (isAppSwitchKeyEventLocked(keyEntry)) {
- if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
- mAppSwitchSawKeyDown = true;
- } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
- if (mAppSwitchSawKeyDown) {
- #if DEBUG_APP_SWITCH
- ALOGD("App switch is pending!");
- #endif
- mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
- mAppSwitchSawKeyDown = false;
- needWake = true;
- }
- }
- }
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
-
-
-
-
- MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
- && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
- && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
- && mInputTargetWaitApplicationHandle != NULL) {
- int32_t displayId = motionEntry->displayId;
- int32_t x = int32_t(motionEntry->pointerCoords[0].
- getAxisValue(AMOTION_EVENT_AXIS_X));
- int32_t y = int32_t(motionEntry->pointerCoords[0].
- getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
- if (touchedWindowHandle != NULL
- && touchedWindowHandle->inputApplicationHandle
- != mInputTargetWaitApplicationHandle) {
-
-
- mNextUnblockedEvent = motionEntry;
- needWake = true;
- }
- }
- break;
- }
- }
-
- return needWake;
- }
从这个函数我们可以看出,在两种情况下,它的返回值为true,一是当加入该键盘事件到mInboundQueue之前,mInboundQueue为空,这表示InputDispatcherThread线程正在睡眠等待InputReaderThread线程的唤醒,因此,它返回true表示要唤醒InputDispatccherThread线程;二是加入该键盘事件到mInboundQueue之前,mInboundQueue不为空,但是此时用户按下的是Home键,按下Home键表示要切换App,我们知道,在切换App时,新的App会把它的键盘消息接收通道注册到InputDispatcher中去,并且会等待InputReader的唤醒,因此,在这种情况下,也需要返回true,表示要唤醒InputDispatccherThread线程。如果不是这两种情况,那么就说明InputDispatccherThread线程现在正在处理前面的键盘事件,不需要唤醒它。回到前面的notifyKey函数中,根据enqueueInboundEventLocked函数的返回值来决定是否要唤醒InputDispatccherThread线程:- if (needWake) {
- mLooper->wake();
- }
这里,假设needWake为true,于是,就会调用mLooper对象的wake函数来唤醒InputDispatccherThread线程了。InputManager 的启动过程中说到过 InputReaderThread 和 InputDispatcherThread,在InputDispatccherThread 被唤醒的时候,会调用:
- bool InputDispatcherThread::threadLoop() {
- mDispatcher->dispatchOnce();
- return true;
- }
- void InputDispatcher::dispatchOnce() {
- nsecs_t nextWakeupTime = LONG_LONG_MAX;
- {
- AutoMutex _l(mLock);
- mDispatcherIsAliveCondition.broadcast();
-
-
-
- if (!haveCommandsLocked()) {
- dispatchOnceInnerLocked(&nextWakeupTime);
- }
-
-
-
- if (runCommandsLockedInterruptible()) {
- nextWakeupTime = LONG_LONG_MIN;
- }
- }
-
-
- nsecs_t currentTime = now();
- int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
- mLooper->pollOnce(timeoutMillis);
- }
它调用dispatchOnceInnerLocked函数来进一步处理这个键盘事件。- void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
- nsecs_t currentTime = now();
-
-
-
-
- if (!mDispatchEnabled) {
- resetKeyRepeatLocked();
- }
-
-
- if (mDispatchFrozen) {
- #if DEBUG_FOCUS
- ALOGD("Dispatch frozen. Waiting some more.");
- #endif
- return;
- }
-
-
-
-
- bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
- if (mAppSwitchDueTime < *nextWakeupTime) {
- *nextWakeupTime = mAppSwitchDueTime;
- }
-
-
-
- if (! mPendingEvent) {
- if (mInboundQueue.isEmpty()) {
- if (isAppSwitchDue) {
-
-
- resetPendingAppSwitchLocked(false);
- isAppSwitchDue = false;
- }
-
-
- if (mKeyRepeatState.lastKeyEntry) {
- if (currentTime >= mKeyRepeatState.nextRepeatTime) {
- mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
- } else {
- if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
- *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
- }
- }
- }
-
-
- if (!mPendingEvent) {
- return;
- }
- } else {
-
- mPendingEvent = mInboundQueue.dequeueAtHead();
- traceInboundQueueLengthLocked();
- }
-
-
- if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
- pokeUserActivityLocked(mPendingEvent);
- }
-
-
- resetANRTimeoutsLocked();
- }
-
-
-
- ALOG_ASSERT(mPendingEvent != NULL);
- bool done = false;
- DropReason dropReason = DROP_REASON_NOT_DROPPED;
- if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
- dropReason = DROP_REASON_POLICY;
- } else if (!mDispatchEnabled) {
- dropReason = DROP_REASON_DISABLED;
- }
-
- if (mNextUnblockedEvent == mPendingEvent) {
- mNextUnblockedEvent = NULL;
- }
-
- switch (mPendingEvent->type) {
- case EventEntry::TYPE_CONFIGURATION_CHANGED: {
- ConfigurationChangedEntry* typedEntry =
- static_cast<ConfigurationChangedEntry*>(mPendingEvent);
- done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED;
- break;
- }
-
- case EventEntry::TYPE_DEVICE_RESET: {
- DeviceResetEntry* typedEntry =
- static_cast<DeviceResetEntry*>(mPendingEvent);
- done = dispatchDeviceResetLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED;
- break;
- }
-
- case EventEntry::TYPE_KEY: {
- KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
- if (isAppSwitchDue) {
- if (isAppSwitchKeyEventLocked(typedEntry)) {
- resetPendingAppSwitchLocked(true);
- isAppSwitchDue = false;
- } else if (dropReason == DROP_REASON_NOT_DROPPED) {
- dropReason = DROP_REASON_APP_SWITCH;
- }
- }
- if (dropReason == DROP_REASON_NOT_DROPPED
- && isStaleEventLocked(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
- }
- done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
- MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
- dropReason = DROP_REASON_APP_SWITCH;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED
- && isStaleEventLocked(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
- }
- done = dispatchMotionLocked(currentTime, typedEntry,
- &dropReason, nextWakeupTime);
- break;
- }
-
- default:
- ALOG_ASSERT(false);
- break;
- }
-
- if (done) {
- if (dropReason != DROP_REASON_NOT_DROPPED) {
- dropInboundEventLocked(mPendingEvent, dropReason);
- }
-
- releasePendingEventLocked();
- *nextWakeupTime = LONG_LONG_MIN;
- }
- }
逻辑忽略先,最后会调用:
- done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
- bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
- DropReason* dropReason, nsecs_t* nextWakeupTime) {
- ......
-
-
- Vector<InputTarget> inputTargets;
- int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
- entry, inputTargets, nextWakeupTime);
- if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
- return false;
- }
-
- setInjectionResultLocked(entry, injectionResult);
- if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
- return true;
- }
-
- addMonitoringTargetsLocked(inputTargets);
-
-
- dispatchEventLocked(currentTime, entry, inputTargets);
- return true;
- }