5656
5757#define INDENT " "
5858#define INDENT2 " "
59+ #define INDENT3 " "
60+ #define INDENT4 " "
5961
6062namespace android {
6163
@@ -78,6 +80,9 @@ const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
7880// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
7981const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL ; // 0.5sec
8082
83+ // Log a warning when an event takes longer than this to process, even if an ANR does not occur.
84+ const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL ; // 2sec
85+
8186
8287static inline nsecs_t now () {
8388 return systemTime (SYSTEM_TIME_MONOTONIC);
@@ -897,11 +902,11 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
897902 const EventEntry* entry,
898903 const sp<InputApplicationHandle>& applicationHandle,
899904 const sp<InputWindowHandle>& windowHandle,
900- nsecs_t * nextWakeupTime) {
905+ nsecs_t * nextWakeupTime, const char * reason ) {
901906 if (applicationHandle == NULL && windowHandle == NULL ) {
902907 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
903908#if DEBUG_FOCUS
904- ALOGD (" Waiting for system to become ready for input." );
909+ ALOGD (" Waiting for system to become ready for input. Reason: %s " , reason );
905910#endif
906911 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
907912 mInputTargetWaitStartTime = currentTime;
@@ -912,8 +917,9 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
912917 } else {
913918 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
914919#if DEBUG_FOCUS
915- ALOGD (" Waiting for application to become ready for input: %s" ,
916- getApplicationWindowLabelLocked (applicationHandle, windowHandle).string ());
920+ ALOGD (" Waiting for application to become ready for input: %s. Reason: %s" ,
921+ getApplicationWindowLabelLocked (applicationHandle, windowHandle).string (),
922+ reason);
917923#endif
918924 nsecs_t timeout;
919925 if (windowHandle != NULL ) {
@@ -946,7 +952,7 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
946952
947953 if (currentTime >= mInputTargetWaitTimeoutTime ) {
948954 onANRLocked (currentTime, applicationHandle, windowHandle,
949- entry->eventTime , mInputTargetWaitStartTime );
955+ entry->eventTime , mInputTargetWaitStartTime , reason );
950956
951957 // Force poll loop to wake up immediately on next iteration once we get the
952958 // ANR response back from the policy.
@@ -1017,13 +1023,11 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
10171023 // then drop the event.
10181024 if (mFocusedWindowHandle == NULL ) {
10191025 if (mFocusedApplicationHandle != NULL ) {
1020- #if DEBUG_FOCUS
1021- ALOGD (" Waiting because there is no focused window but there is a "
1022- " focused application that may eventually add a window: %s." ,
1023- getApplicationWindowLabelLocked (mFocusedApplicationHandle , NULL ).string ());
1024- #endif
10251026 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1026- mFocusedApplicationHandle , NULL , nextWakeupTime);
1027+ mFocusedApplicationHandle , NULL , nextWakeupTime,
1028+ " Waiting because no window has focus but there is a "
1029+ " focused application that may eventually add a window "
1030+ " when it finishes starting up." );
10271031 goto Unresponsive;
10281032 }
10291033
@@ -1040,21 +1044,18 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
10401044
10411045 // If the currently focused window is paused then keep waiting.
10421046 if (mFocusedWindowHandle ->getInfo ()->paused ) {
1043- #if DEBUG_FOCUS
1044- ALOGD (" Waiting because focused window is paused." );
1045- #endif
10461047 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1047- mFocusedApplicationHandle , mFocusedWindowHandle , nextWakeupTime);
1048+ mFocusedApplicationHandle , mFocusedWindowHandle , nextWakeupTime,
1049+ " Waiting because the focused window is paused." );
10481050 goto Unresponsive;
10491051 }
10501052
10511053 // If the currently focused window is still working on previous events then keep waiting.
10521054 if (!isWindowReadyForMoreInputLocked (currentTime, mFocusedWindowHandle , entry)) {
1053- #if DEBUG_FOCUS
1054- ALOGD (" Waiting because focused window still processing previous input." );
1055- #endif
10561055 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1057- mFocusedApplicationHandle , mFocusedWindowHandle , nextWakeupTime);
1056+ mFocusedApplicationHandle , mFocusedWindowHandle , nextWakeupTime,
1057+ " Waiting because the focused window has not finished "
1058+ " processing the input events that were previously delivered to it." );
10581059 goto Unresponsive;
10591060 }
10601061
@@ -1210,11 +1211,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
12101211 // it is invisible) then wait for it. Any other focused window may in
12111212 // fact be in ANR state.
12121213 if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
1213- #if DEBUG_FOCUS
1214- ALOGD (" Waiting because system error window is pending." );
1215- #endif
12161214 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1217- NULL , NULL , nextWakeupTime);
1215+ NULL , NULL , nextWakeupTime,
1216+ " Waiting because a system error window is about to be displayed." );
12181217 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
12191218 goto Unresponsive;
12201219 }
@@ -1241,14 +1240,11 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
12411240 // but not yet put up a window and the user is starting to get impatient.
12421241 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
12431242 && mFocusedApplicationHandle != NULL ) {
1244- #if DEBUG_FOCUS
1245- ALOGD (" Waiting because there is no touched window but there is a "
1246- " focused application that may eventually add a new window: %s." ,
1247- getApplicationWindowLabelLocked (
1248- mFocusedApplicationHandle , NULL ).string ());
1249- #endif
12501243 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1251- mFocusedApplicationHandle , NULL , nextWakeupTime);
1244+ mFocusedApplicationHandle , NULL , nextWakeupTime,
1245+ " Waiting because there is no touchable window that can "
1246+ " handle the event but there is focused application that may "
1247+ " eventually add a new window when it finishes starting up." );
12521248 goto Unresponsive;
12531249 }
12541250
@@ -1412,21 +1408,18 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
14121408 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
14131409 // If the touched window is paused then keep waiting.
14141410 if (touchedWindow.windowHandle ->getInfo ()->paused ) {
1415- #if DEBUG_FOCUS
1416- ALOGD (" Waiting because touched window is paused." );
1417- #endif
14181411 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1419- NULL , touchedWindow.windowHandle , nextWakeupTime);
1412+ NULL , touchedWindow.windowHandle , nextWakeupTime,
1413+ " Waiting because the touched window is paused." );
14201414 goto Unresponsive;
14211415 }
14221416
14231417 // If the touched window is still working on previous events then keep waiting.
14241418 if (!isWindowReadyForMoreInputLocked (currentTime, touchedWindow.windowHandle , entry)) {
1425- #if DEBUG_FOCUS
1426- ALOGD (" Waiting because touched window still processing previous input." );
1427- #endif
14281419 injectionResult = handleTargetsNotReadyLocked (currentTime, entry,
1429- NULL , touchedWindow.windowHandle , nextWakeupTime);
1420+ NULL , touchedWindow.windowHandle , nextWakeupTime,
1421+ " Waiting because the touched window has not finished "
1422+ " processing the input events that were previously delivered to it." );
14301423 goto Unresponsive;
14311424 }
14321425 }
@@ -1897,6 +1890,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
18971890 while (connection->status == Connection::STATUS_NORMAL
18981891 && !connection->outboundQueue .isEmpty ()) {
18991892 DispatchEntry* dispatchEntry = connection->outboundQueue .head ;
1893+ dispatchEntry->deliveryTime = currentTime;
19001894
19011895 // Publish the event.
19021896 status_t status;
@@ -3099,7 +3093,65 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
30993093 dump.append (INDENT " MonitoringChannels: <none>\n " );
31003094 }
31013095
3102- dump.appendFormat (INDENT " InboundQueue: length=%u\n " , mInboundQueue .count ());
3096+ nsecs_t currentTime = now ();
3097+
3098+ if (!mInboundQueue .isEmpty ()) {
3099+ dump.appendFormat (INDENT " InboundQueue: length=%u\n " , mInboundQueue .count ());
3100+ for (EventEntry* entry = mInboundQueue .head ; entry; entry = entry->next ) {
3101+ dump.append (INDENT2);
3102+ entry->appendDescription (dump);
3103+ dump.appendFormat (" , age=%01.1fms\n " ,
3104+ (currentTime - entry->eventTime ) * 0 .000001f );
3105+ }
3106+ } else {
3107+ dump.append (INDENT " InboundQueue: <empty>\n " );
3108+ }
3109+
3110+ if (!mConnectionsByFd .isEmpty ()) {
3111+ dump.append (INDENT " Connections:\n " );
3112+ for (size_t i = 0 ; i < mConnectionsByFd .size (); i++) {
3113+ const sp<Connection>& connection = mConnectionsByFd .valueAt (i);
3114+ dump.appendFormat (INDENT2 " %d: channelName='%s', windowName='%s', "
3115+ " status=%s, monitor=%s, inputPublisherBlocked=%s\n " ,
3116+ i, connection->getInputChannelName (), connection->getWindowName (),
3117+ connection->getStatusLabel (), toString (connection->monitor ),
3118+ toString (connection->inputPublisherBlocked ));
3119+
3120+ if (!connection->outboundQueue .isEmpty ()) {
3121+ dump.appendFormat (INDENT3 " OutboundQueue: length=%u\n " ,
3122+ connection->outboundQueue .count ());
3123+ for (DispatchEntry* entry = connection->outboundQueue .head ; entry;
3124+ entry = entry->next ) {
3125+ dump.append (INDENT4);
3126+ entry->eventEntry ->appendDescription (dump);
3127+ dump.appendFormat (" , targetFlags=0x%08x, resolvedAction=%d, age=%01.1fms\n " ,
3128+ entry->targetFlags , entry->resolvedAction ,
3129+ (currentTime - entry->eventEntry ->eventTime ) * 0 .000001f );
3130+ }
3131+ } else {
3132+ dump.append (INDENT3 " OutboundQueue: <empty>\n " );
3133+ }
3134+
3135+ if (!connection->waitQueue .isEmpty ()) {
3136+ dump.appendFormat (INDENT3 " WaitQueue: length=%u\n " ,
3137+ connection->waitQueue .count ());
3138+ for (DispatchEntry* entry = connection->waitQueue .head ; entry;
3139+ entry = entry->next ) {
3140+ dump.append (INDENT4);
3141+ entry->eventEntry ->appendDescription (dump);
3142+ dump.appendFormat (" , targetFlags=0x%08x, resolvedAction=%d, "
3143+ " age=%01.1fms, wait=%01.1fms\n " ,
3144+ entry->targetFlags , entry->resolvedAction ,
3145+ (currentTime - entry->eventEntry ->eventTime ) * 0 .000001f ,
3146+ (currentTime - entry->deliveryTime ) * 0 .000001f );
3147+ }
3148+ } else {
3149+ dump.append (INDENT3 " WaitQueue: <empty>\n " );
3150+ }
3151+ }
3152+ } else {
3153+ dump.append (INDENT " Connections: <none>\n " );
3154+ }
31033155
31043156 if (isAppSwitchPendingLocked ()) {
31053157 dump.appendFormat (INDENT " AppSwitch: pending, due in %01.1fms\n " ,
@@ -3214,6 +3266,7 @@ void InputDispatcher::onDispatchCycleFinishedLocked(
32143266 CommandEntry* commandEntry = postCommandLocked (
32153267 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
32163268 commandEntry->connection = connection;
3269+ commandEntry->eventTime = currentTime;
32173270 commandEntry->seq = seq;
32183271 commandEntry->handled = handled;
32193272}
@@ -3231,12 +3284,12 @@ void InputDispatcher::onDispatchCycleBrokenLocked(
32313284void InputDispatcher::onANRLocked (
32323285 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
32333286 const sp<InputWindowHandle>& windowHandle,
3234- nsecs_t eventTime, nsecs_t waitStartTime) {
3287+ nsecs_t eventTime, nsecs_t waitStartTime, const char * reason ) {
32353288 ALOGI (" Application is not responding: %s. "
3236- " %01.1fms since event, %01.1fms since wait started" ,
3289+ " It has been %01.1fms since event, %01.1fms since wait started. Reason: %s " ,
32373290 getApplicationWindowLabelLocked (applicationHandle, windowHandle).string (),
32383291 (currentTime - eventTime) / 1000000.0 ,
3239- (currentTime - waitStartTime) / 1000000.0 );
3292+ (currentTime - waitStartTime) / 1000000.0 , reason );
32403293
32413294 CommandEntry* commandEntry = postCommandLocked (
32423295 & InputDispatcher::doNotifyANRLockedInterruptible);
@@ -3308,12 +3361,22 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
33083361void InputDispatcher::doDispatchCycleFinishedLockedInterruptible (
33093362 CommandEntry* commandEntry) {
33103363 sp<Connection> connection = commandEntry->connection ;
3364+ nsecs_t finishTime = commandEntry->eventTime ;
33113365 uint32_t seq = commandEntry->seq ;
33123366 bool handled = commandEntry->handled ;
33133367
33143368 // Handle post-event policy actions.
33153369 DispatchEntry* dispatchEntry = connection->findWaitQueueEntry (seq);
33163370 if (dispatchEntry) {
3371+ nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime ;
3372+ if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
3373+ String8 msg;
3374+ msg.appendFormat (" Window '%s' spent %01.1fms processing the last input event: " ,
3375+ connection->getWindowName (), eventDuration * 0 .000001f );
3376+ dispatchEntry->eventEntry ->appendDescription (msg);
3377+ ALOGI (" %s" , msg.string ());
3378+ }
3379+
33173380 bool restartEvent;
33183381 if (dispatchEntry->eventEntry ->type == EventEntry::TYPE_KEY) {
33193382 KeyEntry* keyEntry = static_cast <KeyEntry*>(dispatchEntry->eventEntry );
@@ -3656,6 +3719,10 @@ InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t ev
36563719InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry () {
36573720}
36583721
3722+ void InputDispatcher::ConfigurationChangedEntry::appendDescription (String8& msg) const {
3723+ msg.append (" ConfigurationChangedEvent()" );
3724+ }
3725+
36593726
36603727// --- InputDispatcher::DeviceResetEntry ---
36613728
@@ -3667,6 +3734,10 @@ InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t d
36673734InputDispatcher::DeviceResetEntry::~DeviceResetEntry () {
36683735}
36693736
3737+ void InputDispatcher::DeviceResetEntry::appendDescription (String8& msg) const {
3738+ msg.appendFormat (" DeviceResetEvent(deviceId=%d)" , deviceId);
3739+ }
3740+
36703741
36713742// --- InputDispatcher::KeyEntry ---
36723743
@@ -3685,6 +3756,11 @@ InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
36853756InputDispatcher::KeyEntry::~KeyEntry () {
36863757}
36873758
3759+ void InputDispatcher::KeyEntry::appendDescription (String8& msg) const {
3760+ msg.appendFormat (" KeyEvent(action=%d, deviceId=%d, source=0x%08x)" ,
3761+ action, deviceId, source);
3762+ }
3763+
36883764void InputDispatcher::KeyEntry::recycle () {
36893765 releaseInjectionState ();
36903766
@@ -3718,6 +3794,11 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
37183794InputDispatcher::MotionEntry::~MotionEntry () {
37193795}
37203796
3797+ void InputDispatcher::MotionEntry::appendDescription (String8& msg) const {
3798+ msg.appendFormat (" MotionEvent(action=%d, deviceId=%d, source=0x%08x)" ,
3799+ action, deviceId, source);
3800+ }
3801+
37213802
37223803// --- InputDispatcher::DispatchEntry ---
37233804
@@ -3728,7 +3809,7 @@ InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
37283809 seq (nextSeq()),
37293810 eventEntry (eventEntry), targetFlags(targetFlags),
37303811 xOffset (xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
3731- resolvedAction (0 ), resolvedFlags(0 ) {
3812+ deliveryTime ( 0 ), resolvedAction(0 ), resolvedFlags(0 ) {
37323813 eventEntry->refCount += 1 ;
37333814}
37343815
0 commit comments