Add TestApi interfaces for window organizers

Enables testing the API surfaces from CTS.

Bug: 149338177
Test: they pass!
Change-Id: I7e1f2852585a10c20d299bd87e9a87f828d06d6a
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 556f841..2531c89 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -73,7 +73,7 @@
 import android.util.DisplayMetrics;
 import android.util.Singleton;
 import android.util.Size;
-import android.window.IWindowContainer;
+import android.window.WindowContainerToken;
 import android.view.Surface;
 
 import com.android.internal.app.LocalePicker;
@@ -2759,7 +2759,7 @@
         // Index of the stack in the display's stack list, can be used for comparison of stack order
         @UnsupportedAppUsage
         public int position;
-        public IWindowContainer stackToken;
+        public WindowContainerToken stackToken;
         /**
          * The full configuration the stack is currently running in.
          * @hide
@@ -2793,7 +2793,7 @@
             dest.writeInt(userId);
             dest.writeInt(visible ? 1 : 0);
             dest.writeInt(position);
-            dest.writeStrongInterface(stackToken);
+            stackToken.writeToParcel(dest, 0);
             if (topActivity != null) {
                 dest.writeInt(1);
                 topActivity.writeToParcel(dest, 0);
@@ -2825,7 +2825,7 @@
             userId = source.readInt();
             visible = source.readInt() > 0;
             position = source.readInt();
-            stackToken = IWindowContainer.Stub.asInterface(source.readStrongBinder());
+            stackToken = WindowContainerToken.CREATOR.createFromParcel(source);
             if (source.readInt() > 0) {
                 topActivity = ComponentName.readFromParcel(source);
             }
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 073b8d0..ab7925c 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -42,6 +42,9 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.window.TaskEmbedder;
+import android.window.TaskOrganizerTaskEmbedder;
+import android.window.VirtualDisplayTaskEmbedder;
 
 import dalvik.system.CloseGuard;
 
@@ -52,11 +55,11 @@
  * @hide
  */
 @TestApi
-public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
+public class ActivityView extends ViewGroup implements android.window.TaskEmbedder.Host {
 
     private static final String TAG = "ActivityView";
 
-    private TaskEmbedder mTaskEmbedder;
+    private android.window.TaskEmbedder mTaskEmbedder;
 
     private final SurfaceView mSurfaceView;
     private final SurfaceCallback mSurfaceCallback;
@@ -487,7 +490,7 @@
 
     /** @hide */
     @Override
-    public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
+    public void onTaskBackgroundColorChanged(android.window.TaskEmbedder ts, int bgColor) {
         if (mSurfaceView != null) {
             mSurfaceView.setResizeBackgroundColor(bgColor);
         }
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 7c0fc42..0173731 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -28,7 +28,7 @@
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.util.Log;
-import android.window.IWindowContainer;
+import android.window.WindowContainerToken;
 
 /**
  * Stores information about a particular Task.
@@ -147,7 +147,7 @@
      * @hide
      */
     @NonNull
-    public IWindowContainer token;
+    public WindowContainerToken token;
 
     /**
      * The PictureInPictureParams for the Task, if set.
@@ -222,7 +222,7 @@
         supportsSplitScreenMultiWindow = source.readBoolean();
         resizeMode = source.readInt();
         configuration.readFromParcel(source);
-        token = IWindowContainer.Stub.asInterface(source.readStrongBinder());
+        token = WindowContainerToken.CREATOR.createFromParcel(source);
         topActivityType = source.readInt();
         pictureInPictureParams = source.readInt() != 0
                 ? PictureInPictureParams.CREATOR.createFromParcel(source)
@@ -265,7 +265,7 @@
         dest.writeBoolean(supportsSplitScreenMultiWindow);
         dest.writeInt(resizeMode);
         configuration.writeToParcel(dest, flags);
-        dest.writeStrongInterface(token);
+        token.writeToParcel(dest, flags);
         dest.writeInt(topActivityType);
         if (pictureInPictureParams == null) {
             dest.writeInt(0);
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
new file mode 100644
index 0000000..eee222b
--- /dev/null
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
+import android.os.RemoteException;
+import android.util.Singleton;
+
+/**
+ * Interface for WindowManager to delegate control of display areas.
+ * @hide
+ */
+@TestApi
+public class DisplayAreaOrganizer extends WindowOrganizer {
+
+    public static final int FEATURE_UNDEFINED = -1;
+    public static final int FEATURE_SYSTEM_FIRST = 0;
+    // The Root display area on a display
+    public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
+    // Display area hosting the task container.
+    public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
+    // Display area hosting non-activity window tokens.
+    public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;
+
+    public static final int FEATURE_SYSTEM_LAST = 10_000;
+
+    // Vendor specific display area definition can start with this value.
+    public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
+
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public void registerOrganizer(int displayAreaFeature) {
+        try {
+            getController().registerOrganizer(mInterface, displayAreaFeature);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {}
+
+    public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {}
+
+
+    private final IDisplayAreaOrganizer mInterface = new IDisplayAreaOrganizer.Stub() {
+
+        @Override
+        public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {
+            DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayArea);
+        }
+
+        @Override
+        public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {
+            DisplayAreaOrganizer.this.onDisplayAreaVanished(displayArea);
+        }
+    };
+
+    private static IDisplayAreaOrganizerController getController() {
+        return IDisplayAreaOrganizerControllerSingleton.get();
+    }
+
+    private static final Singleton<IDisplayAreaOrganizerController>
+            IDisplayAreaOrganizerControllerSingleton =
+            new Singleton<IDisplayAreaOrganizerController>() {
+                @Override
+                protected IDisplayAreaOrganizerController create() {
+                    try {
+                        return getWindowOrganizerController()
+                                .getDisplayAreaOrganizerController();
+                    } catch (RemoteException e) {
+                        return null;
+                    }
+                }
+            };
+
+}
diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl
index 1045ab2..9c72e60 100644
--- a/core/java/android/window/IDisplayAreaOrganizer.aidl
+++ b/core/java/android/window/IDisplayAreaOrganizer.aidl
@@ -16,13 +16,13 @@
 
 package android.window;
 
-import android.window.IWindowContainer;
+import android.window.WindowContainerToken;
 
 /**
  * Interface for WindowManager to delegate control of display areas.
  * {@hide}
  */
 oneway interface IDisplayAreaOrganizer {
-    void onDisplayAreaAppeared(in IWindowContainer displayArea);
-    void onDisplayAreaVanished(in IWindowContainer displayArea);
+    void onDisplayAreaAppeared(in WindowContainerToken displayArea);
+    void onDisplayAreaVanished(in WindowContainerToken displayArea);
 }
diff --git a/core/java/android/window/ITaskOrganizer.aidl b/core/java/android/window/ITaskOrganizer.aidl
index b038b0f..b4f0162 100644
--- a/core/java/android/window/ITaskOrganizer.aidl
+++ b/core/java/android/window/ITaskOrganizer.aidl
@@ -18,7 +18,7 @@
 
 import android.view.SurfaceControl;
 import android.app.ActivityManager;
-import android.window.IWindowContainer;
+import android.window.WindowContainerToken;
 
 /**
  * Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index ba65915..1c03b2f 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -18,7 +18,7 @@
 
 import android.app.ActivityManager;
 import android.window.ITaskOrganizer;
-import android.window.IWindowContainer;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 /** @hide */
@@ -40,23 +40,23 @@
     ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode);
 
     /** Deletes a persistent root task in WM */
-    boolean deleteRootTask(IWindowContainer task);
+    boolean deleteRootTask(in WindowContainerToken task);
 
     /** Gets direct child tasks (ordered from top-to-bottom) */
-    List<ActivityManager.RunningTaskInfo> getChildTasks(in IWindowContainer parent,
+    List<ActivityManager.RunningTaskInfo> getChildTasks(in WindowContainerToken parent,
             in int[] activityTypes);
 
     /** Gets all root tasks on a display (ordered from top-to-bottom) */
     List<ActivityManager.RunningTaskInfo> getRootTasks(int displayId, in int[] activityTypes);
 
     /** Get the root task which contains the current ime target */
-    IWindowContainer getImeTarget(int display);
+    WindowContainerToken getImeTarget(int display);
 
     /**
      * Set's the root task to launch new tasks into on a display. {@code null} means no launch root
      * and thus new tasks just end up directly on the display.
      */
-    void setLaunchRoot(int displayId, in IWindowContainer root);
+    void setLaunchRoot(int displayId, in WindowContainerToken root);
 
     /**
      * Requests that the given task organizer is notified when back is pressed on the root activity
diff --git a/core/java/android/window/IWindowContainer.aidl b/core/java/android/window/IWindowContainerToken.aidl
similarity index 96%
rename from core/java/android/window/IWindowContainer.aidl
rename to core/java/android/window/IWindowContainerToken.aidl
index f2960f6..57c7abf 100644
--- a/core/java/android/window/IWindowContainer.aidl
+++ b/core/java/android/window/IWindowContainerToken.aidl
@@ -23,7 +23,7 @@
  * token.
  * @hide
  */
-interface IWindowContainer {
+interface IWindowContainerToken {
 
     /**
      * Gets a persistent leash for this container or {@code null}.
diff --git a/core/java/android/window/IWindowContainerTransactionCallback.aidl b/core/java/android/window/IWindowContainerTransactionCallback.aidl
index 0579932..eb07965 100644
--- a/core/java/android/window/IWindowContainerTransactionCallback.aidl
+++ b/core/java/android/window/IWindowContainerTransactionCallback.aidl
@@ -24,5 +24,5 @@
  */
 oneway interface IWindowContainerTransactionCallback {
     /** Called upon completion of WindowOrganizer#applyTransaction */
-    void transactionReady(int id, in SurfaceControl.Transaction t);
+    void onTransactionReady(int id, in SurfaceControl.Transaction t);
 }
diff --git a/core/java/android/app/TaskEmbedder.java b/core/java/android/window/TaskEmbedder.java
similarity index 97%
rename from core/java/android/app/TaskEmbedder.java
rename to core/java/android/window/TaskEmbedder.java
index 10c11f2..45ab310 100644
--- a/core/java/android/app/TaskEmbedder.java
+++ b/core/java/android/window/TaskEmbedder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,13 +14,19 @@
  * limitations under the License.
  */
 
-package android.app;
+package android.window;
 
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.app.ActivityView;
+import android.app.IActivityTaskManager;
+import android.app.PendingIntent;
+import android.app.TaskStackListener;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
new file mode 100644
index 0000000..5098b44
--- /dev/null
+++ b/core/java/android/window/TaskOrganizer.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
+import android.app.ActivityManager;
+import android.os.RemoteException;
+import android.util.Singleton;
+
+import java.util.List;
+
+/**
+ * Interface for ActivityTaskManager/WindowManager to delegate control of tasks.
+ * @hide
+ */
+@TestApi
+public class TaskOrganizer extends WindowOrganizer {
+
+    /**
+     * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
+     * If there was already a TaskOrganizer for this windowing mode it will be evicted
+     * and receive taskVanished callbacks in the process.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public void registerOrganizer(int windowingMode) {
+        try {
+            getController().registerTaskOrganizer(mInterface, windowingMode);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Unregisters a previously registered task organizer. */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public void unregisterOrganizer() {
+        try {
+            getController().unregisterTaskOrganizer(mInterface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
+
+    public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
+
+    public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo info) {}
+
+    public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo info) {}
+
+    /** Creates a persistent root task in WM for a particular windowing-mode. */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    @Nullable
+    public static ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) {
+        try {
+            return getController().createRootTask(displayId, windowingMode);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Deletes a persistent root task in WM */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public static boolean deleteRootTask(@NonNull WindowContainerToken task) {
+        try {
+            return getController().deleteRootTask(task);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Gets direct child tasks (ordered from top-to-bottom) */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    @Nullable
+    public static List<ActivityManager.RunningTaskInfo> getChildTasks(
+            @NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
+        try {
+            return getController().getChildTasks(parent, activityTypes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Gets all root tasks on a display (ordered from top-to-bottom) */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    @Nullable
+    public static List<ActivityManager.RunningTaskInfo> getRootTasks(
+            int displayId, @NonNull int[] activityTypes) {
+        try {
+            return getController().getRootTasks(displayId, activityTypes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Get the root task which contains the current ime target */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    @Nullable
+    public static WindowContainerToken getImeTarget(int display) {
+        try {
+            return getController().getImeTarget(display);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set's the root task to launch new tasks into on a display. {@code null} means no launch
+     * root and thus new tasks just end up directly on the display.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public static void setLaunchRoot(int displayId, @NonNull WindowContainerToken root) {
+        try {
+            getController().setLaunchRoot(displayId, root);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Requests that the given task organizer is notified when back is pressed on the root activity
+     * of one of its controlled tasks.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
+        try {
+            getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
+
+        @Override
+        public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+            TaskOrganizer.this.onTaskAppeared(taskInfo);
+        }
+
+        @Override
+        public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+            TaskOrganizer.this.onTaskVanished(taskInfo);
+        }
+
+        @Override
+        public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
+            TaskOrganizer.this.onTaskInfoChanged(info);
+        }
+
+        @Override
+        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
+            TaskOrganizer.this.onBackPressedOnTaskRoot(info);
+        }
+    };
+
+    private static ITaskOrganizerController getController() {
+        return ITaskOrganizerControllerSingleton.get();
+    }
+
+    private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
+            new Singleton<ITaskOrganizerController>() {
+                @Override
+                protected ITaskOrganizerController create() {
+                    try {
+                        return getWindowOrganizerController().getTaskOrganizerController();
+                    } catch (RemoteException e) {
+                        return null;
+                    }
+                }
+            };
+}
diff --git a/core/java/android/app/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java
similarity index 79%
rename from core/java/android/app/TaskOrganizerTaskEmbedder.java
rename to core/java/android/window/TaskOrganizerTaskEmbedder.java
index adc0792..2091c93 100644
--- a/core/java/android/app/TaskOrganizerTaskEmbedder.java
+++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,22 +14,20 @@
  * limitations under the License.
  */
 
-package android.app;
+package android.window;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityView;
+import android.app.TaskStackListener;
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.RemoteException;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.SurfaceControl;
-import android.window.ITaskOrganizer;
-import android.window.IWindowContainer;
-import android.window.WindowContainerTransaction;
-import android.window.WindowOrganizer;
-import android.window.WindowOrganizer.TaskOrganizer;
 
 /**
  * A component which handles embedded display of tasks within another window. The embedded task can
@@ -41,9 +39,9 @@
     private static final String TAG = "TaskOrgTaskEmbedder";
     private static final boolean DEBUG = false;
 
-    private ITaskOrganizer.Stub mTaskOrganizer;
+    private TaskOrganizer mTaskOrganizer;
     private ActivityManager.RunningTaskInfo mTaskInfo;
-    private IWindowContainer mTaskToken;
+    private WindowContainerToken mTaskToken;
     private SurfaceControl mTaskLeash;
     private boolean mPendingNotifyBoundsChanged;
 
@@ -79,16 +77,11 @@
         }
         // Register the task organizer
         mTaskOrganizer =  new TaskOrganizerImpl();
-        try {
-            // TODO(wm-shell): This currently prevents other organizers from controlling MULT_WINDOW
-            // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that
-            // infrastructure is ready.
-            TaskOrganizer.registerOrganizer(mTaskOrganizer, WINDOWING_MODE_MULTI_WINDOW);
-            TaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskOrganizer, true);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to initialize TaskEmbedder", e);
-            return false;
-        }
+        // TODO(wm-shell): This currently prevents other organizers from controlling MULT_WINDOW
+        // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that
+        // infrastructure is ready.
+        mTaskOrganizer.registerOrganizer(WINDOWING_MODE_MULTI_WINDOW);
+        mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
         return true;
     }
 
@@ -100,11 +93,7 @@
         if (!isInitialized()) {
             return false;
         }
-        try {
-            TaskOrganizer.unregisterOrganizer(mTaskOrganizer);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to remove task");
-        }
+        mTaskOrganizer.unregisterOrganizer();
         resetTaskInfo();
         return true;
     }
@@ -125,11 +114,7 @@
         }
         WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.setHidden(mTaskToken, false /* hidden */);
-        try {
-            WindowOrganizer.applyTransaction(wct);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to unset hidden in transaction");
-        }
+        WindowOrganizer.applyTransaction(wct);
         // TODO(b/151449487): Only call callback once we enable synchronization
         if (mListener != null) {
             mListener.onTaskVisibilityChanged(getTaskId(), true);
@@ -152,11 +137,7 @@
         }
         WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.setHidden(mTaskToken, true /* hidden */);
-        try {
-            WindowOrganizer.applyTransaction(wct);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to set hidden in transaction");
-        }
+        WindowOrganizer.applyTransaction(wct);
         // TODO(b/151449487): Only call callback once we enable synchronization
         if (mListener != null) {
             mListener.onTaskVisibilityChanged(getTaskId(), false);
@@ -186,12 +167,8 @@
 
         WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.setBounds(mTaskToken, screenBounds);
-        try {
-            // TODO(b/151449487): Enable synchronization
-            WindowOrganizer.applyTransaction(wct);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to set bounds in transaction");
-        }
+        // TODO(b/151449487): Enable synchronization
+        WindowOrganizer.applyTransaction(wct);
     }
 
     /**
@@ -253,8 +230,7 @@
     private class TaskStackListenerImpl extends TaskStackListener {
 
         @Override
-        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
+        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) {
             if (!isInitialized()) {
                 return;
             }
@@ -266,10 +242,9 @@
         }
     }
 
-    private class TaskOrganizerImpl extends ITaskOrganizer.Stub {
+    private class TaskOrganizerImpl extends TaskOrganizer {
         @Override
-        public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
+        public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
             if (DEBUG) {
                 log("taskAppeared: " + taskInfo.taskId);
             }
@@ -293,8 +268,7 @@
         }
 
         @Override
-        public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
+        public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
             if (DEBUG) {
                 log("taskVanished: " + taskInfo.taskId);
             }
@@ -309,14 +283,7 @@
         }
 
         @Override
-        public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
-            // Do nothing
-        }
-
-        @Override
-        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
+        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
             if (mListener != null) {
                 mListener.onBackPressedOnTaskRoot(taskInfo.taskId);
             }
diff --git a/core/java/android/app/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java
similarity index 97%
rename from core/java/android/app/VirtualDisplayTaskEmbedder.java
rename to core/java/android/window/VirtualDisplayTaskEmbedder.java
index 7ad8f22..0b2dcd8 100644
--- a/core/java/android/app/VirtualDisplayTaskEmbedder.java
+++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.app;
+package android.window;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
@@ -23,6 +23,11 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.app.ActivityView;
+import android.app.TaskStackListener;
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Insets;
@@ -72,7 +77,7 @@
      * @param singleTaskInstance whether to apply a single-task constraint to this container,
      *                           only applicable if virtual displays are used
      */
-    VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
+    public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
             boolean singleTaskInstance) {
         super(context, host);
         mSingleTaskInstance = singleTaskInstance;
diff --git a/core/java/android/window/IWindowContainer.aidl b/core/java/android/window/WindowContainerToken.aidl
similarity index 62%
copy from core/java/android/window/IWindowContainer.aidl
copy to core/java/android/window/WindowContainerToken.aidl
index f2960f6..f22786b 100644
--- a/core/java/android/window/IWindowContainer.aidl
+++ b/core/java/android/window/WindowContainerToken.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,17 +16,4 @@
 
 package android.window;
 
-import android.view.SurfaceControl;
-
-/**
- * Interface for a window container to communicate with the window manager. This also acts as a
- * token.
- * @hide
- */
-interface IWindowContainer {
-
-    /**
-     * Gets a persistent leash for this container or {@code null}.
-     */
-    SurfaceControl getLeash();
-}
+parcelable WindowContainerToken;
diff --git a/core/java/android/window/WindowContainerToken.java b/core/java/android/window/WindowContainerToken.java
new file mode 100644
index 0000000..dde98da
--- /dev/null
+++ b/core/java/android/window/WindowContainerToken.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.view.SurfaceControl;
+import android.window.IWindowContainerToken;
+
+/**
+ * Interface for a window container to communicate with the window manager. This also acts as a
+ * token.
+ * @hide
+ */
+@TestApi
+public final class WindowContainerToken implements Parcelable {
+
+    private final IWindowContainerToken mRealToken;
+
+    /** @hide */
+    public WindowContainerToken(IWindowContainerToken realToken) {
+        mRealToken = realToken;
+    }
+
+    private WindowContainerToken(Parcel in) {
+        mRealToken = IWindowContainerToken.Stub.asInterface(in.readStrongBinder());
+    }
+
+    @Nullable
+    public SurfaceControl getLeash() {
+        try {
+            return mRealToken.getLeash();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** @hide */
+    public IBinder asBinder() {
+        return mRealToken.asBinder();
+    }
+
+    @Override
+    /** @hide */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeStrongBinder(mRealToken.asBinder());
+    }
+
+    @NonNull
+    public static final Creator<WindowContainerToken> CREATOR =
+            new Creator<WindowContainerToken>() {
+                @Override
+                public WindowContainerToken createFromParcel(Parcel in) {
+                    return new WindowContainerToken(in);
+                }
+
+                @Override
+                public WindowContainerToken[] newArray(int size) {
+                    return new WindowContainerToken[size];
+                }
+            };
+
+    @Override
+    /** @hide */
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 483dec6..231e024 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.app.WindowConfiguration;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -26,7 +27,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
-import android.window.IWindowContainer;
 import android.view.SurfaceControl;
 
 import java.util.ArrayList;
@@ -39,7 +39,8 @@
  *
  * @hide
  */
-public class WindowContainerTransaction implements Parcelable {
+@TestApi
+public final class WindowContainerTransaction implements Parcelable {
     private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
 
     // Flat list because re-order operations are order-dependent
@@ -47,7 +48,7 @@
 
     public WindowContainerTransaction() {}
 
-    protected WindowContainerTransaction(Parcel in) {
+    private WindowContainerTransaction(Parcel in) {
         in.readMap(mChanges, null /* loader */);
         in.readList(mHierarchyOps, null /* loader */);
     }
@@ -64,7 +65,9 @@
     /**
      * Resize a container.
      */
-    public WindowContainerTransaction setBounds(IWindowContainer container, Rect bounds) {
+    @NonNull
+    public WindowContainerTransaction setBounds(
+            @NonNull WindowContainerToken container,@NonNull Rect bounds) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mConfiguration.windowConfiguration.setBounds(bounds);
         chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -77,7 +80,9 @@
      * app's DisplayInfo. It is derived by subtracting the overlapping portion of the navbar from
      * the full bounds.
      */
-    public WindowContainerTransaction setAppBounds(IWindowContainer container, Rect appBounds) {
+    @NonNull
+    public WindowContainerTransaction setAppBounds(
+            @NonNull WindowContainerToken container,@NonNull Rect appBounds) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mConfiguration.windowConfiguration.setAppBounds(appBounds);
         chg.mConfigSetMask |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -91,7 +96,9 @@
      * derived by subtracting the overlapping portions of both the statusbar and the navbar from
      * the full bounds.
      */
-    public WindowContainerTransaction setScreenSizeDp(IWindowContainer container, int w, int h) {
+    @NonNull
+    public WindowContainerTransaction setScreenSizeDp(
+            @NonNull WindowContainerToken container, int w, int h) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mConfiguration.screenWidthDp = w;
         chg.mConfiguration.screenHeightDp = h;
@@ -100,11 +107,12 @@
     }
 
     /**
-     * Notify activies within the hiearchy of a container that they have entered picture-in-picture
+     * Notify activities within the hierarchy of a container that they have entered picture-in-picture
      * mode with the given bounds.
      */
-    public WindowContainerTransaction scheduleFinishEnterPip(IWindowContainer container,
-            Rect bounds) {
+    @NonNull
+    public WindowContainerTransaction scheduleFinishEnterPip(
+            @NonNull WindowContainerToken container,@NonNull Rect bounds) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mPinnedBounds = new Rect(bounds);
         chg.mChangeMask |= Change.CHANGE_PIP_CALLBACK;
@@ -123,8 +131,9 @@
      * that you can call this, apply the WindowContainer transaction, and then later call
      * dismissPip() to achieve synchronization.
      */
-    public WindowContainerTransaction setBoundsChangeTransaction(IWindowContainer container,
-            SurfaceControl.Transaction t) {
+    @NonNull
+    public WindowContainerTransaction setBoundsChangeTransaction(
+            @NonNull WindowContainerToken container,@NonNull SurfaceControl.Transaction t) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mBoundsChangeTransaction = t;
         chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION;
@@ -139,8 +148,9 @@
      *
      * TODO(b/134365562): Can be removed once TaskOrg drives full-screen
      */
-    public WindowContainerTransaction setActivityWindowingMode(IWindowContainer container,
-            int windowingMode) {
+    @NonNull
+    public WindowContainerTransaction setActivityWindowingMode(
+            @NonNull WindowContainerToken container, int windowingMode) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mActivityWindowingMode = windowingMode;
         return this;
@@ -149,8 +159,9 @@
     /**
      * Sets the windowing mode of the given container.
      */
-    public WindowContainerTransaction setWindowingMode(IWindowContainer container,
-            int windowingMode) {
+    @NonNull
+    public WindowContainerTransaction setWindowingMode(
+            @NonNull WindowContainerToken container, int windowingMode) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mWindowingMode = windowingMode;
         return this;
@@ -161,7 +172,9 @@
      * child can be focused; however, when {@code true}, it is still possible for children to be
      * non-focusable due to WM policy.
      */
-    public WindowContainerTransaction setFocusable(IWindowContainer container, boolean focusable) {
+    @NonNull
+    public WindowContainerTransaction setFocusable(
+            @NonNull WindowContainerToken container, boolean focusable) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mFocusable = focusable;
         chg.mChangeMask |= Change.CHANGE_FOCUSABLE;
@@ -173,7 +186,9 @@
      * visibility of the container applies, but when {@code true} the container will be forced
      * to be hidden.
      */
-    public WindowContainerTransaction setHidden(IWindowContainer container, boolean hidden) {
+    @NonNull
+    public WindowContainerTransaction setHidden(
+            @NonNull WindowContainerToken container, boolean hidden) {
         Change chg = getOrCreateChange(container.asBinder());
         chg.mHidden = hidden;
         chg.mChangeMask |= Change.CHANGE_HIDDEN;
@@ -183,8 +198,9 @@
     /**
      * Set the smallestScreenWidth of a container.
      */
-    public WindowContainerTransaction setSmallestScreenWidthDp(IWindowContainer container,
-            int widthDp) {
+    @NonNull
+    public WindowContainerTransaction setSmallestScreenWidthDp(
+            @NonNull WindowContainerToken container, int widthDp) {
         Change cfg = getOrCreateChange(container.asBinder());
         cfg.mConfiguration.smallestScreenWidthDp = widthDp;
         cfg.mConfigSetMask |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
@@ -198,8 +214,9 @@
      * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
      *              the bottom.
      */
-    public WindowContainerTransaction reparent(@NonNull IWindowContainer child,
-            @Nullable IWindowContainer parent, boolean onTop) {
+    @NonNull
+    public WindowContainerTransaction reparent(@NonNull WindowContainerToken child,
+            @Nullable WindowContainerToken parent, boolean onTop) {
         mHierarchyOps.add(new HierarchyOp(child.asBinder(),
                 parent == null ? null : parent.asBinder(), onTop));
         return this;
@@ -211,36 +228,43 @@
      * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
      *              the bottom.
      */
-    public WindowContainerTransaction reorder(@NonNull IWindowContainer child, boolean onTop) {
+    @NonNull
+    public WindowContainerTransaction reorder(@NonNull WindowContainerToken child, boolean onTop) {
         mHierarchyOps.add(new HierarchyOp(child.asBinder(), onTop));
         return this;
     }
 
+    /** @hide */
     public Map<IBinder, Change> getChanges() {
         return mChanges;
     }
 
+    /** @hide */
     public List<HierarchyOp> getHierarchyOps() {
         return mHierarchyOps;
     }
 
     @Override
+    @NonNull
     public String toString() {
         return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps
                 + " }";
     }
 
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    /** @hide */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeMap(mChanges);
         dest.writeList(mHierarchyOps);
     }
 
     @Override
+    /** @hide */
     public int describeContents() {
         return 0;
     }
 
+    @NonNull
     public static final Creator<WindowContainerTransaction> CREATOR =
             new Creator<WindowContainerTransaction>() {
                 @Override
@@ -256,7 +280,6 @@
 
     /**
      * Holds changes on a single WindowContainer including Configuration changes.
-     *
      * @hide
      */
     public static class Change implements Parcelable {
@@ -430,6 +453,7 @@
     /**
      * Holds information about a reparent/reorder operation in the hierarchy. This is separate from
      * Changes because they must be executed in the same order that they are added.
+     * @hide
      */
     public static class HierarchyOp implements Parcelable {
         private final IBinder mContainer;
diff --git a/core/java/android/window/WindowContainerTransactionCallback.java b/core/java/android/window/WindowContainerTransactionCallback.java
new file mode 100644
index 0000000..67cb1e7
--- /dev/null
+++ b/core/java/android/window/WindowContainerTransactionCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.window;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.view.SurfaceControl;
+
+
+/**
+ * See WindowOrganizer#applyTransaction.
+ * {@hide}
+ */
+@TestApi
+public abstract class WindowContainerTransactionCallback {
+
+    public abstract void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t);
+
+    /** @hide */
+    final IWindowContainerTransactionCallback mInterface =
+            new IWindowContainerTransactionCallback.Stub() {
+        @Override
+        public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+            WindowContainerTransactionCallback.this.onTransactionReady(id, t);
+        }
+    };
+}
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index 5590e72..4578271 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -16,29 +16,32 @@
 
 package android.window;
 
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
-import android.app.ActivityManager;
+import android.annotation.TestApi;
 import android.app.ActivityTaskManager;
 import android.os.RemoteException;
 import android.util.Singleton;
 
-import java.util.List;
-
 /**
- * Class for organizing specific types of windows like Tasks and DisplayAreas
+ * Base class for organizing specific types of windows like Tasks and DisplayAreas
  *
  * @hide
  */
+@TestApi
 public class WindowOrganizer {
 
     /**
      * Apply multiple WindowContainer operations at once.
      * @param t The transaction to apply.
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-    public static void applyTransaction(WindowContainerTransaction t) throws RemoteException {
-        getWindowOrganizerController().applyTransaction(t);
+    public static void applyTransaction(@NonNull WindowContainerTransaction t) {
+        try {
+            getWindowOrganizerController().applyTransaction(t);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -49,17 +52,19 @@
      *        WindowContainer transaction will be passed to this callback when ready.
      * @return An ID for the sync operation which will later be passed to transactionReady callback.
      *         This lets the caller differentiate overlapping sync operations.
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-    public static int applySyncTransaction(WindowContainerTransaction t,
-            IWindowContainerTransactionCallback callback) throws RemoteException {
-        return getWindowOrganizerController().applySyncTransaction(t, callback);
+    public int applySyncTransaction(@NonNull WindowContainerTransaction t,
+            @NonNull WindowContainerTransactionCallback callback) {
+        try {
+            return getWindowOrganizerController().applySyncTransaction(t, callback.mInterface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
-    /** @hide */
     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-    private static IWindowOrganizerController getWindowOrganizerController() {
+    static IWindowOrganizerController getWindowOrganizerController() {
         return IWindowOrganizerControllerSingleton.get();
     }
 
@@ -74,138 +79,4 @@
                     }
                 }
             };
-
-    public static class TaskOrganizer {
-
-        /**
-         * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
-         * If there was already a TaskOrganizer for this windowing mode it will be evicted
-         * and receive taskVanished callbacks in the process.
-         */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static void registerOrganizer(ITaskOrganizer organizer, int windowingMode)
-                throws RemoteException {
-            getController().registerTaskOrganizer(organizer, windowingMode);
-        }
-
-        /** Unregisters a previously registered task organizer. */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static void unregisterOrganizer(ITaskOrganizer organizer) throws RemoteException {
-            getController().unregisterTaskOrganizer(organizer);
-        }
-
-        /** Creates a persistent root task in WM for a particular windowing-mode. */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static ActivityManager.RunningTaskInfo createRootTask(
-                int displayId, int windowingMode) throws RemoteException {
-            return getController().createRootTask(displayId, windowingMode);
-        }
-
-        /** Deletes a persistent root task in WM */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static boolean deleteRootTask(IWindowContainer task) throws RemoteException {
-            return getController().deleteRootTask(task);
-        }
-
-        /** Gets direct child tasks (ordered from top-to-bottom) */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static List<ActivityManager.RunningTaskInfo> getChildTasks(IWindowContainer parent,
-                int[] activityTypes) throws RemoteException {
-            return getController().getChildTasks(parent, activityTypes);
-        }
-
-        /** Gets all root tasks on a display (ordered from top-to-bottom) */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static List<ActivityManager.RunningTaskInfo> getRootTasks(
-                int displayId, int[] activityTypes) throws RemoteException {
-            return getController().getRootTasks(displayId, activityTypes);
-        }
-
-        /** Get the root task which contains the current ime target */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static IWindowContainer getImeTarget(int display) throws RemoteException {
-            return getController().getImeTarget(display);
-        }
-
-        /**
-         * Set's the root task to launch new tasks into on a display. {@code null} means no launch
-         * root and thus new tasks just end up directly on the display.
-         */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static void setLaunchRoot(int displayId, IWindowContainer root)
-                throws RemoteException {
-            getController().setLaunchRoot(displayId, root);
-        }
-
-        /**
-         * Requests that the given task organizer is notified when back is pressed on the root
-         * activity of one of its controlled tasks.
-         */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
-                boolean interceptBackPressed) throws RemoteException {
-            getController().setInterceptBackPressedOnTaskRoot(organizer, interceptBackPressed);
-        }
-
-        private static ITaskOrganizerController getController() {
-            return ITaskOrganizerControllerSingleton.get();
-        }
-
-        private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
-                new Singleton<ITaskOrganizerController>() {
-                    @Override
-                    protected ITaskOrganizerController create() {
-                        try {
-                            return getWindowOrganizerController().getTaskOrganizerController();
-                        } catch (RemoteException e) {
-                            return null;
-                        }
-                    }
-                };
-    }
-
-    /** Class for organizing display areas. */
-    public static class DisplayAreaOrganizer {
-
-        public static final int FEATURE_UNDEFINED = -1;
-        public static final int FEATURE_SYSTEM_FIRST = 0;
-        // The Root display area on a display
-        public static final int FEATURE_ROOT = FEATURE_SYSTEM_FIRST;
-        // Display area hosting the task container.
-        public static final int FEATURE_TASK_CONTAINER = FEATURE_SYSTEM_FIRST + 1;
-        // Display area hosting non-activity window tokens.
-        public static final int FEATURE_WINDOW_TOKENS = FEATURE_SYSTEM_FIRST + 2;
-
-        public static final int FEATURE_SYSTEM_LAST = 10_000;
-
-        // Vendor specific display area definition can start with this value.
-        public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1;
-
-        /** @hide */
-        @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
-        public static void registerOrganizer(
-                IDisplayAreaOrganizer organizer, int displayAreaFeature) throws RemoteException {
-            getController().registerOrganizer(organizer, displayAreaFeature);
-        }
-
-        /** @hide */
-        private static IDisplayAreaOrganizerController getController() {
-            return IDisplayAreaOrganizerControllerSingleton.get();
-        }
-
-        private static final Singleton<IDisplayAreaOrganizerController>
-                IDisplayAreaOrganizerControllerSingleton =
-                new Singleton<IDisplayAreaOrganizerController>() {
-                    @Override
-                    protected IDisplayAreaOrganizerController create() {
-                        try {
-                            return getWindowOrganizerController()
-                                    .getDisplayAreaOrganizerController();
-                        } catch (RemoteException e) {
-                            return null;
-                        }
-                    }
-                };
-
-    }
 }