diff options
Diffstat (limited to 'libs/ui/InputDispatcher.cpp')
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index f9c0b91..299b1ba 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -1770,13 +1770,14 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, } void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, - const sp<Connection>& connection) { + const sp<Connection>& connection, bool handled) { #if DEBUG_DISPATCH_CYCLE LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, " - "%01.1fms since dispatch", + "%01.1fms since dispatch, handled=%s", connection->getInputChannelName(), connection->getEventLatencyMillis(currentTime), - connection->getDispatchLatencyMillis(currentTime)); + connection->getDispatchLatencyMillis(currentTime), + toString(handled)); #endif if (connection->status == Connection::STATUS_BROKEN @@ -1784,9 +1785,6 @@ void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, return; } - // Notify other system components. - onDispatchCycleFinishedLocked(currentTime, connection); - // Reset the publisher since the event has been consumed. // We do this now so that the publisher can release some of its internal resources // while waiting for the next dispatch cycle to begin. @@ -1798,7 +1796,8 @@ void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, return; } - startNextDispatchCycleLocked(currentTime, connection); + // Notify other system components and prepare to start the next dispatch cycle. + onDispatchCycleFinishedLocked(currentTime, connection, handled); } void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime, @@ -1898,7 +1897,8 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data return 1; } - status_t status = connection->inputPublisher.receiveFinishedSignal(); + bool handled = false; + status_t status = connection->inputPublisher.receiveFinishedSignal(handled); if (status) { LOGE("channel '%s' ~ Failed to receive finished signal. status=%d", connection->getInputChannelName(), status); @@ -1907,7 +1907,7 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data return 0; // remove the callback } - d->finishDispatchCycleLocked(currentTime, connection); + d->finishDispatchCycleLocked(currentTime, connection, handled); d->runCommandsLockedInterruptible(); return 1; } // release lock @@ -2945,7 +2945,11 @@ void InputDispatcher::onDispatchCycleStartedLocked( } void InputDispatcher::onDispatchCycleFinishedLocked( - nsecs_t currentTime, const sp<Connection>& connection) { + nsecs_t currentTime, const sp<Connection>& connection, bool handled) { + CommandEntry* commandEntry = postCommandLocked( + & InputDispatcher::doDispatchCycleFinishedLockedInterruptible); + commandEntry->connection = connection; + commandEntry->handled = handled; } void InputDispatcher::onDispatchCycleBrokenLocked( @@ -3014,9 +3018,7 @@ void InputDispatcher::doNotifyANRLockedInterruptible( void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible( CommandEntry* commandEntry) { KeyEntry* entry = commandEntry->keyEntry; - mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags, - entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount, - entry->downTime, entry->eventTime); + initializeKeyEvent(&mReusableKeyEvent, entry); mLock.unlock(); @@ -3031,6 +3033,31 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible( mAllocator.releaseKeyEntry(entry); } +void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( + CommandEntry* commandEntry) { + sp<Connection> connection = commandEntry->connection; + bool handled = commandEntry->handled; + + if (!handled && !connection->outboundQueue.isEmpty()) { + DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next; + if (dispatchEntry->inProgress + && dispatchEntry->hasForegroundTarget() + && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) { + KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry); + initializeKeyEvent(&mReusableKeyEvent, keyEntry); + + mLock.unlock(); + + mPolicy->dispatchUnhandledKey(connection->inputChannel, + & mReusableKeyEvent, keyEntry->policyFlags); + + mLock.lock(); + } + } + + startNextDispatchCycleLocked(now(), connection); +} + void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) { mLock.unlock(); @@ -3039,6 +3066,12 @@ void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* comman mLock.lock(); } +void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) { + event->initialize(entry->deviceId, entry->source, entry->action, entry->flags, + entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount, + entry->downTime, entry->eventTime); +} + void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry, int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) { // TODO Write some statistics about how long we spend waiting. |