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/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 6147885..0a48758 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -47,7 +47,6 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.logWithStack;
 
-import android.content.pm.ActivityInfo;
 import android.os.Debug;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.input.InputApplicationHandle;
@@ -173,8 +172,10 @@
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
             boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
-            int configChanges, boolean launchTaskBehind, boolean alwaysFocusable) {
+            int configChanges, boolean launchTaskBehind, boolean alwaysFocusable,
+            AppWindowContainerController controller) {
         this(service, token, voiceInteraction, dc);
+        setController(controller);
         mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
         mFillsParent = fullscreen;
         mShowForAllUsers = showForAllUsers;
@@ -251,9 +252,12 @@
         }
         if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
                 + numInteresting + " visible=" + numVisible);
+        final AppWindowContainerController controller = getController();
         if (nowDrawn != reportedDrawn) {
             if (nowDrawn) {
-                mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_DRAWN, this).sendToTarget();
+                if (controller != null) {
+                    controller.reportWindowsDrawn();
+                }
             }
             reportedDrawn = nowDrawn;
         }
@@ -261,8 +265,13 @@
             if (DEBUG_VISIBILITY) Slog.v(TAG,
                     "Visibility changed in " + this + ": vis=" + nowVisible);
             reportedVisible = nowVisible;
-            mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_WINDOWS,
-                    nowVisible ? 1 : 0, nowGone ? 1 : 0, this).sendToTarget();
+            if (controller != null) {
+                if (nowVisible) {
+                    controller.reportWindowsVisible();
+                } else {
+                    controller.reportWindowsGone();
+                }
+            }
         }
     }
 
@@ -399,6 +408,11 @@
         return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
     }
 
+    AppWindowContainerController getController() {
+        final WindowContainerController controller = super.getController();
+        return controller != null ? (AppWindowContainerController) controller : null;
+    }
+
     @Override
     boolean isVisible() {
         // If the app token isn't hidden then it is considered visible and there is no need to check