Tell system server whether the app handled input events.
Refactored ViewRoot, NativeActivity and related classes to tell the dispatcher whether an input event was actually handled by the application. This will be used to move more of the global default key processing into the system server instead of the application. Change-Id: If06b98b6f45c543e5ac5b1eae2b3baf9371fba28
This commit is contained in:
@ -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.
|
||||
|
Reference in New Issue
Block a user