Skip to content

Commit 22aa512

Browse files
author
Jeff Brown
committed
Capture input dispatcher's last ANR state in bug report.
Some ANR bugs are very difficult to localize because by the time the bug report has been captured, the relevant information is gone. Work around this by capturing a log of the input dispatcher's state at the exact time of the ANR before anything has changed and include this information in the bug report. Also fixed a nit related to some format strings that had improper field widths specified. Bug: 6680398 Change-Id: I5323bf18ec5e47a767cd053209753cc46852bf4c
1 parent c4637d3 commit 22aa512

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

services/input/InputDispatcher.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <unistd.h>
5454
#include <errno.h>
5555
#include <limits.h>
56+
#include <time.h>
5657

5758
#define INDENT " "
5859
#define INDENT2 " "
@@ -1073,7 +1074,7 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
10731074
injectionResult, timeSpentWaitingForApplication);
10741075
#if DEBUG_FOCUS
10751076
ALOGD("findFocusedWindow finished: injectionResult=%d, "
1076-
"timeSpendWaitingForApplication=%0.1fms",
1077+
"timeSpentWaitingForApplication=%0.1fms",
10771078
injectionResult, timeSpentWaitingForApplication / 1000000.0);
10781079
#endif
10791080
return injectionResult;
@@ -3100,7 +3101,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
31003101
for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
31013102
dump.append(INDENT2);
31023103
entry->appendDescription(dump);
3103-
dump.appendFormat(", age=%01.1fms\n",
3104+
dump.appendFormat(", age=%0.1fms\n",
31043105
(currentTime - entry->eventTime) * 0.000001f);
31053106
}
31063107
} else {
@@ -3124,7 +3125,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
31243125
entry = entry->next) {
31253126
dump.append(INDENT4);
31263127
entry->eventEntry->appendDescription(dump);
3127-
dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%01.1fms\n",
3128+
dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
31283129
entry->targetFlags, entry->resolvedAction,
31293130
(currentTime - entry->eventEntry->eventTime) * 0.000001f);
31303131
}
@@ -3140,7 +3141,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
31403141
dump.append(INDENT4);
31413142
entry->eventEntry->appendDescription(dump);
31423143
dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
3143-
"age=%01.1fms, wait=%01.1fms\n",
3144+
"age=%0.1fms, wait=%0.1fms\n",
31443145
entry->targetFlags, entry->resolvedAction,
31453146
(currentTime - entry->eventEntry->eventTime) * 0.000001f,
31463147
(currentTime - entry->deliveryTime) * 0.000001f);
@@ -3154,11 +3155,17 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
31543155
}
31553156

31563157
if (isAppSwitchPendingLocked()) {
3157-
dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
3158+
dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
31583159
(mAppSwitchDueTime - now()) / 1000000.0);
31593160
} else {
31603161
dump.append(INDENT "AppSwitch: not pending\n");
31613162
}
3163+
3164+
dump.append(INDENT "Configuration:\n");
3165+
dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
3166+
mConfig.keyRepeatDelay * 0.000001f);
3167+
dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
3168+
mConfig.keyRepeatTimeout * 0.000001f);
31623169
}
31633170

31643171
status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
@@ -3285,11 +3292,28 @@ void InputDispatcher::onANRLocked(
32853292
nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
32863293
const sp<InputWindowHandle>& windowHandle,
32873294
nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
3295+
float dispatchLatency = (currentTime - eventTime) * 0.000001f;
3296+
float waitDuration = (currentTime - waitStartTime) * 0.000001f;
32883297
ALOGI("Application is not responding: %s. "
3289-
"It has been %01.1fms since event, %01.1fms since wait started. Reason: %s",
3298+
"It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
32903299
getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
3291-
(currentTime - eventTime) / 1000000.0,
3292-
(currentTime - waitStartTime) / 1000000.0, reason);
3300+
dispatchLatency, waitDuration, reason);
3301+
3302+
// Capture a record of the InputDispatcher state at the time of the ANR.
3303+
time_t t = time(NULL);
3304+
struct tm tm;
3305+
localtime_r(&t, &tm);
3306+
char timestr[64];
3307+
strftime(timestr, sizeof(timestr), "%F %T", &tm);
3308+
mLastANRState.clear();
3309+
mLastANRState.append(INDENT "ANR:\n");
3310+
mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
3311+
mLastANRState.appendFormat(INDENT2 "Window: %s\n",
3312+
getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
3313+
mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
3314+
mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
3315+
mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
3316+
dumpDispatchStateLocked(mLastANRState);
32933317

32943318
CommandEntry* commandEntry = postCommandLocked(
32953319
& InputDispatcher::doNotifyANRLockedInterruptible);
@@ -3371,7 +3395,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
33713395
nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
33723396
if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
33733397
String8 msg;
3374-
msg.appendFormat("Window '%s' spent %01.1fms processing the last input event: ",
3398+
msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
33753399
connection->getWindowName(), eventDuration * 0.000001f);
33763400
dispatchEntry->eventEntry->appendDescription(msg);
33773401
ALOGI("%s", msg.string());
@@ -3634,9 +3658,10 @@ void InputDispatcher::dump(String8& dump) {
36343658
dump.append("Input Dispatcher State:\n");
36353659
dumpDispatchStateLocked(dump);
36363660

3637-
dump.append(INDENT "Configuration:\n");
3638-
dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
3639-
dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
3661+
if (!mLastANRState.isEmpty()) {
3662+
dump.append("\nInput Dispatcher State at time of last ANR:\n");
3663+
dump.append(mLastANRState);
3664+
}
36403665
}
36413666

36423667
void InputDispatcher::monitor() {

services/input/InputDispatcher.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,9 @@ class InputDispatcher : public InputDispatcherInterface {
948948
// Focused application.
949949
sp<InputApplicationHandle> mFocusedApplicationHandle;
950950

951+
// Dispatcher state at time of last ANR.
952+
String8 mLastANRState;
953+
951954
// Dispatch inbound events.
952955
bool dispatchConfigurationChangedLocked(
953956
nsecs_t currentTime, ConfigurationChangedEntry* entry);

0 commit comments

Comments
 (0)