Support for WindowContainer controllers and listeners

- WindowContainerController class allows a component outside window manager
to create a window container and communicate directly with it to make
changes. For example, the ActivityRecord class in activity manager uses the
AppWindowContainerController class to create and communicate with
AppWindowToken window container class which is its counterpart on the window
manager side.
- WindowContainerListener interface allows a component outside WM to get
notified of changes to a window container. For example, the ActivityRecord
class in AM implements the AppWindowContainerListener interface to get
notified of changes to the AppWindowToken container.

Bug: 30060889
Test: Existing tests pass and manual testing.
Test: bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
Test: bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
Change-Id: I2896bfa46a80b227052528c7da8cf4e56beab4bc
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 3fbe36f..f754775 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -251,16 +251,14 @@
         }
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
-            try {
-                // Notify the activity manager about the timeout and let it decide whether
-                // to abort dispatching or keep waiting.
-                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
-                if (! abort) {
-                    // The activity manager declined to abort dispatching.
-                    // Wait a bit longer and timeout again later.
-                    return appWindowToken.mInputDispatchingTimeoutNanos;
-                }
-            } catch (RemoteException ex) {
+            // 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);
+            if (!abort) {
+                // The activity manager declined to abort dispatching.
+                // Wait a bit longer and timeout again later.
+                return appWindowToken.mInputDispatchingTimeoutNanos;
             }
         } else if (windowState != null) {
             try {