diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 9a1cd8c3884b8..2f61038bc2309 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1820,14 +1820,22 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } @Override - public boolean keyDispatchingTimedOut(String reason) { + public boolean keyDispatchingTimedOut(String reason, int windowPid) { ActivityRecord anrActivity; ProcessRecord anrApp; + boolean windowFromSameProcessAsActivity; synchronized (service) { anrActivity = getWaitingHistoryRecordLocked(); anrApp = app; + windowFromSameProcessAsActivity = app == null || app.pid == windowPid; + } + if (windowFromSameProcessAsActivity) { + return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason); + } else { + // In this case another process added windows using this activity token. So, we call the + // generic service input dispatch timed out method so that the right process is blamed. + return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0; } - return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason); } private ActivityRecord getWaitingHistoryRecordLocked() { diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index e60295de4876e..4b4be40880ee6 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -706,8 +706,8 @@ public class AppWindowContainerController } /** Calls directly into activity manager so window manager lock shouldn't held. */ - boolean keyDispatchingTimedOut(String reason) { - return mListener != null && mListener.keyDispatchingTimedOut(reason); + boolean keyDispatchingTimedOut(String reason, int windowPid) { + return mListener != null && mListener.keyDispatchingTimedOut(reason, windowPid); } @Override diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java index 9d459cfccc09d..26537f27bce81 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerListener.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java @@ -33,6 +33,10 @@ public interface AppWindowContainerListener extends WindowContainerListener { /** * Called when the key dispatching to a window associated with the app window container * timed-out. + * + * @param reason The reason for the key dispatching time out. + * @param windowPid The pid of the window key dispatching timed out on. + * @return True if input dispatching should be aborted. */ - boolean keyDispatchingTimedOut(String reason); + boolean keyDispatchingTimedOut(String reason, int windowPid); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index d041c111a8884..aae216e0d47cf 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -258,7 +258,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // Notify the activity manager about the timeout and let it decide whether // to abort dispatching or keep waiting. final AppWindowContainerController controller = appWindowToken.getController(); - final boolean abort = controller != null && controller.keyDispatchingTimedOut(reason); + final boolean abort = controller != null + && controller.keyDispatchingTimedOut(reason, windowState.mSession.mPid); if (!abort) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. @@ -281,7 +282,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { return 0; // abort dispatching } - void addInputWindowHandle(final InputWindowHandle windowHandle) { + private void addInputWindowHandle(final InputWindowHandle windowHandle) { if (mInputWindowHandles == null) { mInputWindowHandles = new InputWindowHandle[16]; }