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;
- }
- }
- };
-
- }
}