WM: Blame the window from the focus request for ANR
If there are no focusable windows, then try to blame the window that was requested to become focused. This will avoid blaming the wrong process when WM requests focus on a window that is placed on top of the focused app and the window fails to become focusable. Test: atest android.server.wm.AnrTests Test: steps from bug Bug: b/23990703 Change-Id: Ibf74086de259a671c77fcee9746048a3a440bcc4
This commit is contained in:
@@ -19,6 +19,7 @@ package com.android.server.wm;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
import static com.android.server.wm.ActivityRecord.INVALID_PID;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutMillisLocked;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -72,6 +73,33 @@ class AnrController {
|
||||
+ ". Dropping notifyNoFocusedWindowAnr request");
|
||||
return;
|
||||
}
|
||||
|
||||
// App is unresponsive, but we are actively trying to give focus to a window.
|
||||
// Blame the window if possible since the window may not belong to the app.
|
||||
DisplayContent display = mService.mRoot.getDisplayContent(activity.getDisplayId());
|
||||
IBinder focusToken = display == null ? null : display.getInputMonitor().mInputFocus;
|
||||
InputTarget focusTarget = mService.getInputTargetFromToken(focusToken);
|
||||
|
||||
if (focusTarget != null) {
|
||||
// Check if we have a recent focus request, newer than the dispatch timeout, then
|
||||
// ignore the focus request.
|
||||
WindowState targetWindowState = focusTarget.getWindowState();
|
||||
boolean requestIsValid = SystemClock.uptimeMillis()
|
||||
- display.getInputMonitor().mInputFocusRequestTimeMillis
|
||||
>= getInputDispatchingTimeoutMillisLocked(
|
||||
targetWindowState.getActivityRecord());
|
||||
|
||||
if (requestIsValid) {
|
||||
if (notifyWindowUnresponsive(focusToken, timeoutRecord)) {
|
||||
Slog.i(TAG_WM, "Blamed " + focusTarget.getWindowState().getName()
|
||||
+ " using pending focus request. Focused activity: "
|
||||
+ activity.getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Slog.i(TAG_WM, "ANR in " + activity.getName() + ". Reason: " + timeoutRecord.mReason);
|
||||
dumpAnrStateLocked(activity, null /* windowState */, timeoutRecord.mReason);
|
||||
mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
|
||||
@@ -208,6 +236,7 @@ class AnrController {
|
||||
}
|
||||
}
|
||||
mService.mAmInternal.inputDispatchingResumed(unresponsiveApp.getPid());
|
||||
mUnresponsiveAppByDisplay.remove(newFocus.getDisplayId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,6 +52,7 @@ import android.graphics.Region;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.InputConfig;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
@@ -77,7 +78,8 @@ final class InputMonitor {
|
||||
private final WindowManagerService mService;
|
||||
|
||||
// Current input focus token for keys and other non-touch events. May be null.
|
||||
private IBinder mInputFocus = null;
|
||||
IBinder mInputFocus = null;
|
||||
long mInputFocusRequestTimeMillis = 0;
|
||||
|
||||
// When true, need to call updateInputWindowsLw().
|
||||
private boolean mUpdateInputWindowsNeeded = true;
|
||||
@@ -479,6 +481,7 @@ final class InputMonitor {
|
||||
}
|
||||
|
||||
mInputFocus = focusToken;
|
||||
mInputFocusRequestTimeMillis = SystemClock.uptimeMillis();
|
||||
mInputTransaction.setFocusedWindow(mInputFocus, windowName, mDisplayId);
|
||||
EventLog.writeEvent(LOGTAG_INPUT_FOCUS, "Focus request " + windowName,
|
||||
"reason=UpdateInputWindows");
|
||||
|
||||
Reference in New Issue
Block a user