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
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 9a1cd8c..2f61038 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 @@
     }
 
     @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;
         }
-        return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
+        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;
+        }
     }
 
     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 e60295d..4b4be40 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 @@
     }
 
     /** 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 9d459cf..26537f2 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 @@
     /**
      * 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 d041c11..aae216e 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 @@
             // 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 @@
         return 0; // abort dispatching
     }
 
-    void addInputWindowHandle(final InputWindowHandle windowHandle) {
+    private void addInputWindowHandle(final InputWindowHandle windowHandle) {
         if (mInputWindowHandles == null) {
             mInputWindowHandles = new InputWindowHandle[16];
         }