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
31643171status_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 (" \n Input Dispatcher State at time of last ANR:\n " );
3663+ dump.append (mLastANRState );
3664+ }
36403665}
36413666
36423667void InputDispatcher::monitor () {
0 commit comments