Limit the number of printed entries in a queue
When debugging some input bugs, it takes a while to scroll through all
of the entries in waitQueues and outboundQueues.
For example, the count can be > 100 for some ANR scenarios.
Limit the number to 50 total entries printed: 25 oldest and 25 newest.
This quantity should be sufficient to figure out what's going on with
the queues.
Note: I could not reproduce the ANR anymore, so the latest patchset was
not tested using the first test procedure.
Bug: 160561987
Test: reproduce an ANR using monkey, then look at dumpsys input
adb shell monkey 10000
adb shell dumpsys input
Test: the above procedure, but without 'reproduce ANR'
Change-Id: I01d661e0a85cc5bfbf61fa4b23689e8b27daa84b
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 4328e03..34fa239 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -70,12 +70,6 @@
releaseInjectionState();
}
-std::string EventEntry::getDescription() const {
- std::string result;
- appendDescription(result);
- return result;
-}
-
void EventEntry::release() {
refCount -= 1;
if (refCount == 0) {
@@ -99,8 +93,8 @@
ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
-void ConfigurationChangedEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
+std::string ConfigurationChangedEntry::getDescription() const {
+ return StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
}
// --- DeviceResetEntry ---
@@ -110,8 +104,8 @@
DeviceResetEntry::~DeviceResetEntry() {}
-void DeviceResetEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
+std::string DeviceResetEntry::getDescription() const {
+ return StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
}
// --- FocusEntry ---
@@ -126,8 +120,8 @@
FocusEntry::~FocusEntry() {}
-void FocusEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
+std::string FocusEntry::getDescription() const {
+ return StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
}
// --- KeyEntry ---
@@ -153,12 +147,11 @@
KeyEntry::~KeyEntry() {}
-void KeyEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("KeyEvent");
+std::string KeyEntry::getDescription() const {
if (!GetBoolProperty("ro.debuggable", false)) {
- return;
+ return "KeyEvent";
}
- msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
+ return StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
"flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
"repeatCount=%d), policyFlags=0x%08x",
deviceId, source, displayId, KeyEvent::actionToString(action), flags,
@@ -212,12 +205,12 @@
MotionEntry::~MotionEntry() {}
-void MotionEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("MotionEvent");
+std::string MotionEntry::getDescription() const {
if (!GetBoolProperty("ro.debuggable", false)) {
- return;
+ return "MotionEvent";
}
- msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
+ std::string msg;
+ msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
"buttonState=0x%08x, "
"classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
@@ -235,6 +228,7 @@
pointerCoords[i].getY());
}
msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
+ return msg;
}
// --- DispatchEntry ---
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index d5b589e..ace57f1 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -81,9 +81,7 @@
void release();
- virtual void appendDescription(std::string& msg) const = 0;
-
- std::string getDescription() const;
+ virtual std::string getDescription() const = 0;
protected:
EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
@@ -93,7 +91,7 @@
struct ConfigurationChangedEntry : EventEntry {
explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~ConfigurationChangedEntry();
@@ -103,7 +101,7 @@
int32_t deviceId;
DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~DeviceResetEntry();
@@ -116,7 +114,7 @@
FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
std::string_view reason);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~FocusEntry();
@@ -148,7 +146,7 @@
KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
int32_t metaState, int32_t repeatCount, nsecs_t downTime);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
void recycle();
protected:
@@ -182,7 +180,7 @@
float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xOffset, float yOffset);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~MotionEntry();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 8b4ae03..22e658a 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -217,6 +217,36 @@
}
}
+static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
+ constexpr size_t maxEntries = 50; // max events to print
+ constexpr size_t skipBegin = maxEntries / 2;
+ const size_t skipEnd = queue.size() - maxEntries / 2;
+ // skip from maxEntries / 2 ... size() - maxEntries/2
+ // only print from 0 .. skipBegin and then from skipEnd .. size()
+
+ std::string dump;
+ for (size_t i = 0; i < queue.size(); i++) {
+ const DispatchEntry& entry = *queue[i];
+ if (i >= skipBegin && i < skipEnd) {
+ dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
+ i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
+ continue;
+ }
+ dump.append(INDENT4);
+ dump += entry.eventEntry->getDescription();
+ dump += StringPrintf(", seq=%" PRIu32
+ ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
+ entry.seq, entry.targetFlags, entry.resolvedAction,
+ ns2ms(currentTime - entry.eventEntry->eventTime));
+ if (entry.deliveryTime != 0) {
+ // This entry was delivered, so add information on how long we've been waiting
+ dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
+ }
+ dump.append("\n");
+ }
+ return dump;
+}
+
/**
* Find the entry in std::unordered_map by key, and return it.
* If the entry is not found, return a default constructed entry.
@@ -4454,7 +4484,7 @@
dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
for (EventEntry* entry : mRecentQueue) {
dump += INDENT2;
- entry->appendDescription(dump);
+ dump += entry->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
}
} else {
@@ -4465,7 +4495,7 @@
if (mPendingEvent) {
dump += INDENT "PendingEvent:\n";
dump += INDENT2;
- mPendingEvent->appendDescription(dump);
+ dump += mPendingEvent->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n",
ns2ms(currentTime - mPendingEvent->eventTime));
} else {
@@ -4477,7 +4507,7 @@
dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
for (EventEntry* entry : mInboundQueue) {
dump += INDENT2;
- entry->appendDescription(dump);
+ dump += entry->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
}
} else {
@@ -4509,14 +4539,8 @@
if (!connection->outboundQueue.empty()) {
dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
connection->outboundQueue.size());
- for (DispatchEntry* entry : connection->outboundQueue) {
- dump.append(INDENT4);
- entry->eventEntry->appendDescription(dump);
- dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64
- "ms\n",
- entry->targetFlags, entry->resolvedAction,
- ns2ms(currentTime - entry->eventEntry->eventTime));
- }
+ dump += dumpQueue(connection->outboundQueue, currentTime);
+
} else {
dump += INDENT3 "OutboundQueue: <empty>\n";
}
@@ -4524,15 +4548,7 @@
if (!connection->waitQueue.empty()) {
dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
connection->waitQueue.size());
- for (DispatchEntry* entry : connection->waitQueue) {
- dump += INDENT4;
- entry->eventEntry->appendDescription(dump);
- dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
- "age=%" PRId64 "ms, wait=%" PRId64 "ms seq=%" PRIu32 "\n",
- entry->targetFlags, entry->resolvedAction,
- ns2ms(currentTime - entry->eventEntry->eventTime),
- ns2ms(currentTime - entry->deliveryTime), entry->seq);
- }
+ dump += dumpQueue(connection->waitQueue, currentTime);
} else {
dump += INDENT3 "WaitQueue: <empty>\n";
}