Skip to content

Commit edded60

Browse files
author
Zhenghua Wang
committed
Input: Fix some Applications ANR issue in monkey test
Issue Description: When do monkey test on some applications, there is big probability get ANR issue. one example is as following: adb shell monkey -p com.google.android.street -v 500000 Root Cause: situation 1. InputDispatcher Thread calls findTouchedWindowTargetsLocked routine, there is a AMOTION_EVENT_ACTION_DOWN event and it can find a splittable touched window for this event , then mTouchState.split set to true. situation 2. WMS Thread calls setInputWindows routine and all TouchedWindows associated with mTouchState are removed , mTouchState.split status still keep true. situation 3. InputDispatcher Thread calls findTouchedWindowTargetsLocked routine, there is a AMOTION_EVENT_ACTION_POINTER_DOWN event and it can find found touched window, exit window loop in following code : if (windowInfo->visible) { if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) { isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0; if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) { if (! screenWasOff || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) { newTouchedWindowHandle = windowHandle; } break; // found touched window, exit window loop } } situation 4. The following code will have problem after situation 3 in below conditions: newTouchedWindowHandle doesn't support split , isSplit is true ( last time touched window is splittable ) mTempTouchState.getFirstForegroundWindowHandle will always return NULL due to situation 2 // Figure out whether splitting will be allowed for this window. if (newTouchedWindowHandle != NULL && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) { // New window supports splitting. isSplit = true; } else if (isSplit) { // New window does not support splitting but we have already split events. // Assign the pointer to the first foreground window we find. // (May be NULL which is why we put this code block before the next check.) newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle(); } The window says it does not want to support splitting, so the touches should go to one of the previously split windows except that there are none, which result to "goto Unresponsive" in findtouchedWindowTargetsLocked routine. This is not the correct behavior because the user did actually touch something. situation 5. InputDispatcher Thread will call dispatchOnce repeated to try to dispatch this AMOTION_EVENT_ACTION_POINTER_DOWN event, then ANR timeout ( 5000ms ) will be exceeded after several times "goto Unresponsive"in findtouchedWindowTargetsLocked routine. Solution: In situation 4 we should drop the touch. If the newly touched window was splittable then we wouldn't drop the touch. It's only when the newly touched window was not splittable where we will drop the touch. Change-Id: Iab2c06ce0597ac77eb886ccd9d84646c86723bdb Author: Jeffrey Brown <jeffbrown@android.com> Author: Erjun Ding <erjunx.ding@intel.com> Author: Zhenghua Wang <zhenghua.wang@intel.com> Author: Jack Ren <jack.ren@intel.com> Author: Bruce Beare <bruce.j.beare@intel.com>
1 parent 23cad6e commit edded60

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

services/input/InputDispatcher.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,28 +1390,35 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
13901390
// New window supports splitting.
13911391
isSplit = true;
13921392
} else if (isSplit) {
1393-
// New window does not support splitting but we have already split events.
1394-
// Assign the pointer to the first foreground window we find.
1395-
// (May be NULL which is why we put this code block before the next check.)
1396-
newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
1393+
// Ignore the new window.
1394+
newTouchedWindowHandle = NULL;
13971395
}
13981396

1399-
// If we did not find a touched window then fail.
1397+
// Handle the case where we did not find a window.
14001398
if (newTouchedWindowHandle == NULL) {
1401-
if (mFocusedApplicationHandle != NULL) {
1399+
// Try to assign the pointer to the first foreground window we find, if there is one.
1400+
newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
1401+
if (newTouchedWindowHandle == NULL) {
1402+
// There is no touched window. If this is an initial down event
1403+
// then wait for a window to appear that will handle the touch. This is
1404+
// to ensure that we report an ANR in the case where an application has started
1405+
// but not yet put up a window and the user is starting to get impatient.
1406+
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1407+
&& mFocusedApplicationHandle != NULL) {
14021408
#if DEBUG_FOCUS
1403-
ALOGD("Waiting because there is no touched window but there is a "
1404-
"focused application that may eventually add a new window: %s.",
1405-
getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
1409+
ALOGD("Waiting because there is no touched window but there is a "
1410+
"focused application that may eventually add a new window: %s.",
1411+
getApplicationWindowLabelLocked(
1412+
mFocusedApplicationHandle, NULL).string());
14061413
#endif
1407-
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1408-
mFocusedApplicationHandle, NULL, nextWakeupTime);
1409-
goto Unresponsive;
1414+
injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1415+
mFocusedApplicationHandle, NULL, nextWakeupTime);
1416+
goto Unresponsive;
1417+
}
1418+
ALOGI("Dropping event because there is no touched window.");
1419+
injectionResult = INPUT_EVENT_INJECTION_FAILED;
1420+
goto Failed;
14101421
}
1411-
1412-
ALOGI("Dropping event because there is no touched window or focused application.");
1413-
injectionResult = INPUT_EVENT_INJECTION_FAILED;
1414-
goto Failed;
14151422
}
14161423

14171424
// Set target flags.

0 commit comments

Comments
 (0)