Use std::map for fallback keys
Before this CL, custom data structures were used to store fallback keys.
Those structures have some known bugs. To fix this, convert to std::map
and use std::optional to store the result of fallback key lookup.
Bug: 278299254
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: Id37c41694d0b4cfa2ae107b7db13e9389d21c562
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index c39c408..d6bf5e8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -6197,7 +6197,7 @@
// Get the fallback key state.
// Clear it out after dispatching the UP.
int32_t originalKeyCode = keyEntry.keyCode;
- int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
+ std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
connection->inputState.removeFallbackKey(originalKeyCode);
}
@@ -6206,7 +6206,7 @@
// If the application handles the original key for which we previously
// generated a fallback or if the window is not a foreground window,
// then cancel the associated fallback key, if any.
- if (fallbackKeyCode != -1) {
+ if (fallbackKeyCode) {
// Dispatch the unhandled key to the policy with the cancel flag.
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
@@ -6225,12 +6225,12 @@
mLock.lock();
// Cancel the fallback key.
- if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
+ if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
"application handled the original non-fallback key "
"or is no longer a foreground target, "
"canceling previously dispatched fallback key");
- options.keyCode = fallbackKeyCode;
+ options.keyCode = *fallbackKeyCode;
synthesizeCancelationEventsForConnectionLocked(connection, options);
}
connection->inputState.removeFallbackKey(originalKeyCode);
@@ -6240,7 +6240,7 @@
// that we are in a good state to perform unhandled key event processing
// Then ask the policy what to do with it.
bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
- if (fallbackKeyCode == -1 && !initialDown) {
+ if (!fallbackKeyCode && !initialDown) {
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
ALOGD("Unhandled key event: Skipping unhandled key event processing "
"since this is not an initial down. "
@@ -6275,53 +6275,53 @@
// The fallback keycode cannot change at any other point in the lifecycle.
if (initialDown) {
if (fallback) {
- fallbackKeyCode = event.getKeyCode();
+ *fallbackKeyCode = event.getKeyCode();
} else {
- fallbackKeyCode = AKEYCODE_UNKNOWN;
+ *fallbackKeyCode = AKEYCODE_UNKNOWN;
}
- connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
+ connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
}
- ALOG_ASSERT(fallbackKeyCode != -1);
+ ALOG_ASSERT(fallbackKeyCode);
// Cancel the fallback key if the policy decides not to send it anymore.
// We will continue to dispatch the key to the policy but we will no
// longer dispatch a fallback key to the application.
- if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
- (!fallback || fallbackKeyCode != event.getKeyCode())) {
+ if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
+ (!fallback || *fallbackKeyCode != event.getKeyCode())) {
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
if (fallback) {
ALOGD("Unhandled key event: Policy requested to send key %d"
"as a fallback for %d, but on the DOWN it had requested "
"to send %d instead. Fallback canceled.",
- event.getKeyCode(), originalKeyCode, fallbackKeyCode);
+ event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
} else {
ALOGD("Unhandled key event: Policy did not request fallback for %d, "
"but on the DOWN it had requested to send %d. "
"Fallback canceled.",
- originalKeyCode, fallbackKeyCode);
+ originalKeyCode, *fallbackKeyCode);
}
}
CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
"canceling fallback, policy no longer desires it");
- options.keyCode = fallbackKeyCode;
+ options.keyCode = *fallbackKeyCode;
synthesizeCancelationEventsForConnectionLocked(connection, options);
fallback = false;
- fallbackKeyCode = AKEYCODE_UNKNOWN;
+ *fallbackKeyCode = AKEYCODE_UNKNOWN;
if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
- connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
+ connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
}
}
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
{
std::string msg;
- const KeyedVector<int32_t, int32_t>& fallbackKeys =
+ const std::map<int32_t, int32_t>& fallbackKeys =
connection->inputState.getFallbackKeys();
- for (size_t i = 0; i < fallbackKeys.size(); i++) {
- msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
+ for (const auto& [key, value] : fallbackKeys) {
+ msg += StringPrintf(", %d->%d", key, value);
}
ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
fallbackKeys.size(), msg.c_str());
@@ -6335,7 +6335,7 @@
keyEntry.source = event.getSource();
keyEntry.displayId = event.getDisplayId();
keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
- keyEntry.keyCode = fallbackKeyCode;
+ keyEntry.keyCode = *fallbackKeyCode;
keyEntry.scanCode = event.getScanCode();
keyEntry.metaState = event.getMetaState();
keyEntry.repeatCount = event.getRepeatCount();
@@ -6345,7 +6345,7 @@
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
ALOGD("Unhandled key event: Dispatching fallback key. "
"originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
- originalKeyCode, fallbackKeyCode, keyEntry.metaState);
+ originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
}
return true; // restart the event
} else {