From 7402ddf9b45efc9616676205534ce7b4fc3a13e6 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Wed, 29 Mar 2017 12:58:24 -0700 Subject: [PATCH] Correctly blame ANR on process using another process token Activities can give their window tokens to other process to add windows with. E.g. -1 screen on launcher. We were in correctly blaming the process that gave out its token when an ANR occurs because we were looking at the process associated with the activity. This CL fixes that. Test: manual Change-Id: I08fca00d12ab89dc27eb104115fd375bb4e8ec66 Fixes: 36730136 --- .../java/com/android/server/am/ActivityRecord.java | 12 ++++++++++-- .../server/wm/AppWindowContainerController.java | 4 ++-- .../server/wm/AppWindowContainerListener.java | 6 +++++- .../java/com/android/server/wm/InputMonitor.java | 5 +++-- 4 files changed, 20 insertions(+), 7 deletions(-) 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]; }