Changed createRootTask task to be completely async
Currently some of the information about a task created by createRootTask is returned with the method and the rest like leash is return in onTaskAppear. Mixing both async and sync infromation return styles complicates the mental model for this. So, we will have this be completely aync for now. Also, fixed an issue where the windowing mode for organizer created task was not set correctly before the organizer gets the first task appear signal. Bug: 169266958 Test: Split-screen works! Change-Id: Ia4180d5a42838bf566fbf75f40466dfd8237e0f1
This commit is contained in:
@@ -2375,7 +2375,7 @@ package android.window {
|
||||
|
||||
public class TaskOrganizer extends android.window.WindowOrganizer {
|
||||
ctor public TaskOrganizer();
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.app.ActivityManager.RunningTaskInfo createRootTask(int, int);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void createRootTask(int, int, @Nullable android.os.IBinder);
|
||||
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean deleteRootTask(@NonNull android.window.WindowContainerToken);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]);
|
||||
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public android.window.WindowContainerToken getImeTarget(int);
|
||||
|
||||
@@ -241,6 +241,7 @@ public class TaskInfo {
|
||||
|
||||
/** @hide */
|
||||
public void addLaunchCookie(IBinder cookie) {
|
||||
if (cookie == null || launchCookies.contains(cookie)) return;
|
||||
launchCookies.add(cookie);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ interface ITaskOrganizerController {
|
||||
void unregisterTaskOrganizer(ITaskOrganizer organizer);
|
||||
|
||||
/** Creates a persistent root task in WM for a particular windowing-mode. */
|
||||
ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode);
|
||||
void createRootTask(int displayId, int windowingMode, IBinder launchCookie);
|
||||
|
||||
/** Deletes a persistent root task in WM */
|
||||
boolean deleteRootTask(in WindowContainerToken task);
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
@@ -101,12 +102,18 @@ public class TaskOrganizer extends WindowOrganizer {
|
||||
@BinderThread
|
||||
public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
|
||||
|
||||
/** Creates a persistent root task in WM for a particular windowing-mode. */
|
||||
/**
|
||||
* Creates a persistent root task in WM for a particular windowing-mode.
|
||||
* @param displayId The display to create the root task on.
|
||||
* @param windowingMode Windowing mode to put the root task in.
|
||||
* @param launchCookie Launch cookie to associate with the task so that is can be identified
|
||||
* when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
|
||||
@Nullable
|
||||
public ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode) {
|
||||
public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
|
||||
try {
|
||||
return mTaskOrganizerController.createRootTask(displayId, windowingMode);
|
||||
mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -2923,6 +2923,12 @@
|
||||
"group": "WM_DEBUG_ORIENTATION",
|
||||
"at": "com\/android\/server\/wm\/TaskDisplayArea.java"
|
||||
},
|
||||
"1396893178": {
|
||||
"message": "createRootTask unknown displayId=%d",
|
||||
"level": "ERROR",
|
||||
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||
"at": "com\/android\/server\/wm\/TaskOrganizerController.java"
|
||||
},
|
||||
"1401295262": {
|
||||
"message": "Mode default, asking user",
|
||||
"level": "WARN",
|
||||
|
||||
@@ -37,6 +37,18 @@
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
|
||||
},
|
||||
"-1325223370": {
|
||||
"message": "Task appeared taskId=%d listener=%s",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
|
||||
},
|
||||
"-1312360667": {
|
||||
"message": "createRootTask() displayId=%d winMode=%d listener=%s",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
|
||||
},
|
||||
"-1006733970": {
|
||||
"message": "Display added: %d",
|
||||
"level": "VERBOSE",
|
||||
@@ -61,6 +73,12 @@
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/LetterboxTaskListener.java"
|
||||
},
|
||||
"-842742255": {
|
||||
"message": "%s onTaskAppeared unknown taskId=%d winMode=%d",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java"
|
||||
},
|
||||
"-712674749": {
|
||||
"message": "Clip description: %s",
|
||||
"level": "VERBOSE",
|
||||
@@ -73,11 +91,11 @@
|
||||
"group": "WM_SHELL_DRAG_AND_DROP",
|
||||
"at": "com\/android\/wm\/shell\/draganddrop\/DragLayout.java"
|
||||
},
|
||||
"-460572385": {
|
||||
"message": "Task appeared taskId=%d",
|
||||
"-679492476": {
|
||||
"message": "%s onTaskAppeared Primary taskId=%d",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/ShellTaskOrganizer.java"
|
||||
"at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java"
|
||||
},
|
||||
"-191422040": {
|
||||
"message": "Transition animations finished, notifying core %s",
|
||||
@@ -85,6 +103,12 @@
|
||||
"group": "WM_SHELL_TRANSITIONS",
|
||||
"at": "com\/android\/wm\/shell\/Transitions.java"
|
||||
},
|
||||
"154313206": {
|
||||
"message": "%s onTaskAppeared Secondary taskId=%d",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java"
|
||||
},
|
||||
"157713005": {
|
||||
"message": "Task info changed taskId=%d",
|
||||
"level": "VERBOSE",
|
||||
@@ -162,6 +186,12 @@
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_DRAG_AND_DROP",
|
||||
"at": "com\/android\/wm\/shell\/draganddrop\/DragAndDropController.java"
|
||||
},
|
||||
"2135461748": {
|
||||
"message": "%s onTaskAppeared Supported",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_SHELL_TASK_ORG",
|
||||
"at": "com\/android\/wm\/shell\/splitscreen\/SplitScreenTaskListener.java"
|
||||
}
|
||||
},
|
||||
"groups": {
|
||||
|
||||
@@ -20,8 +20,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
|
||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
|
||||
@@ -29,6 +27,7 @@ import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG
|
||||
import android.annotation.IntDef;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.WindowConfiguration.WindowingMode;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
@@ -63,15 +62,13 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
public static final int TASK_LISTENER_TYPE_FULLSCREEN = -2;
|
||||
public static final int TASK_LISTENER_TYPE_MULTI_WINDOW = -3;
|
||||
public static final int TASK_LISTENER_TYPE_PIP = -4;
|
||||
public static final int TASK_LISTENER_TYPE_SPLIT_SCREEN = -5;
|
||||
public static final int TASK_LISTENER_TYPE_LETTERBOX = -6;
|
||||
public static final int TASK_LISTENER_TYPE_LETTERBOX = -5;
|
||||
|
||||
@IntDef(prefix = {"TASK_LISTENER_TYPE_"}, value = {
|
||||
TASK_LISTENER_TYPE_UNDEFINED,
|
||||
TASK_LISTENER_TYPE_FULLSCREEN,
|
||||
TASK_LISTENER_TYPE_MULTI_WINDOW,
|
||||
TASK_LISTENER_TYPE_PIP,
|
||||
TASK_LISTENER_TYPE_SPLIT_SCREEN,
|
||||
TASK_LISTENER_TYPE_LETTERBOX,
|
||||
})
|
||||
public @interface TaskListenerType {}
|
||||
@@ -139,6 +136,14 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
}
|
||||
}
|
||||
|
||||
public void createRootTask(int displayId, int windowingMode, TaskListener listener) {
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s",
|
||||
displayId, windowingMode, listener.toString());
|
||||
final IBinder cookie = new Binder();
|
||||
setPendingLaunchCookieListener(cookie, listener);
|
||||
super.createRootTask(displayId, windowingMode, cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener for a specific task id.
|
||||
*/
|
||||
@@ -238,10 +243,10 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
|
||||
private void onTaskAppeared(TaskAppearedInfo info) {
|
||||
final int taskId = info.getTaskInfo().taskId;
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG, "Task appeared taskId=%d", taskId);
|
||||
mTasks.put(taskId, info);
|
||||
final TaskListener listener =
|
||||
getTaskListener(info.getTaskInfo(), true /*removeLaunchCookieIfNeeded*/);
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG, "Task appeared taskId=%d listener=%s", taskId, listener);
|
||||
if (listener != null) {
|
||||
listener.onTaskAppeared(info.getTaskInfo(), info.getLeash());
|
||||
}
|
||||
@@ -336,7 +341,7 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
}
|
||||
|
||||
@WindowingMode
|
||||
private static int getWindowingMode(RunningTaskInfo taskInfo) {
|
||||
public static int getWindowingMode(RunningTaskInfo taskInfo) {
|
||||
return taskInfo.configuration.windowConfiguration.getWindowingMode();
|
||||
}
|
||||
|
||||
@@ -350,9 +355,6 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
: TASK_LISTENER_TYPE_FULLSCREEN;
|
||||
case WINDOWING_MODE_MULTI_WINDOW:
|
||||
return TASK_LISTENER_TYPE_MULTI_WINDOW;
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
|
||||
case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
|
||||
return TASK_LISTENER_TYPE_SPLIT_SCREEN;
|
||||
case WINDOWING_MODE_PINNED:
|
||||
return TASK_LISTENER_TYPE_PIP;
|
||||
case WINDOWING_MODE_FREEFORM:
|
||||
@@ -370,8 +372,6 @@ public class ShellTaskOrganizer extends TaskOrganizer {
|
||||
return "TASK_LISTENER_TYPE_LETTERBOX";
|
||||
case TASK_LISTENER_TYPE_MULTI_WINDOW:
|
||||
return "TASK_LISTENER_TYPE_MULTI_WINDOW";
|
||||
case TASK_LISTENER_TYPE_SPLIT_SCREEN:
|
||||
return "TASK_LISTENER_TYPE_SPLIT_SCREEN";
|
||||
case TASK_LISTENER_TYPE_PIP:
|
||||
return "TASK_LISTENER_TYPE_PIP";
|
||||
case TASK_LISTENER_TYPE_UNDEFINED:
|
||||
|
||||
@@ -40,7 +40,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
|
||||
|
||||
private static final float ADJUSTED_NONFOCUS_DIM = 0.3f;
|
||||
|
||||
private final SplitScreenTaskOrganizer mSplits;
|
||||
private final SplitScreenTaskListener mSplits;
|
||||
private final TransactionPool mTransactionPool;
|
||||
private final Handler mHandler;
|
||||
private final TaskOrganizer mTaskOrganizer;
|
||||
@@ -92,7 +92,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
|
||||
private boolean mPausedTargetAdjusted = false;
|
||||
private boolean mAdjustedWhileHidden = false;
|
||||
|
||||
DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler,
|
||||
DividerImeController(SplitScreenTaskListener splits, TransactionPool pool, Handler handler,
|
||||
TaskOrganizer taskOrganizer) {
|
||||
mSplits = splits;
|
||||
mTransactionPool = pool;
|
||||
|
||||
@@ -155,7 +155,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
private boolean mAdjustedForIme;
|
||||
private DividerState mState;
|
||||
|
||||
private SplitScreenTaskOrganizer mTiles;
|
||||
private SplitScreenTaskListener mTiles;
|
||||
boolean mFirstLayout = true;
|
||||
int mDividerPositionX;
|
||||
int mDividerPositionY;
|
||||
@@ -354,7 +354,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
|
||||
void injectDependencies(SplitScreenController splitScreenController,
|
||||
DividerWindowManager windowManager, DividerState dividerState,
|
||||
DividerCallbacks callback, SplitScreenTaskOrganizer tiles, SplitDisplayLayout sdl,
|
||||
DividerCallbacks callback, SplitScreenTaskListener tiles, SplitDisplayLayout sdl,
|
||||
DividerImeController imeController, WindowManagerProxy wmProxy) {
|
||||
mSplitScreenController = splitScreenController;
|
||||
mWindowManager = windowManager;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SplitDisplayLayout {
|
||||
|
||||
private static final int DIVIDER_WIDTH_INACTIVE_DP = 4;
|
||||
|
||||
SplitScreenTaskOrganizer mTiles;
|
||||
SplitScreenTaskListener mTiles;
|
||||
DisplayLayout mDisplayLayout;
|
||||
Context mContext;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SplitDisplayLayout {
|
||||
Rect mAdjustedPrimary = null;
|
||||
Rect mAdjustedSecondary = null;
|
||||
|
||||
public SplitDisplayLayout(Context ctx, DisplayLayout dl, SplitScreenTaskOrganizer taskTiles) {
|
||||
public SplitDisplayLayout(Context ctx, DisplayLayout dl, SplitScreenTaskListener taskTiles) {
|
||||
mTiles = taskTiles;
|
||||
mDisplayLayout = dl;
|
||||
mContext = ctx;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class SplitScreenController implements SplitScreen,
|
||||
private final DividerState mDividerState = new DividerState();
|
||||
private final ForcedResizableInfoActivityController mForcedResizableController;
|
||||
private final Handler mHandler;
|
||||
private final SplitScreenTaskOrganizer mSplits;
|
||||
private final SplitScreenTaskListener mSplits;
|
||||
private final SystemWindows mSystemWindows;
|
||||
final TransactionPool mTransactionPool;
|
||||
private final WindowManagerProxy mWindowManagerProxy;
|
||||
@@ -117,7 +117,7 @@ public class SplitScreenController implements SplitScreen,
|
||||
mTransactionPool = transactionPool;
|
||||
mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer);
|
||||
mTaskOrganizer = shellTaskOrganizer;
|
||||
mSplits = new SplitScreenTaskOrganizer(this, shellTaskOrganizer);
|
||||
mSplits = new SplitScreenTaskListener(this, shellTaskOrganizer);
|
||||
mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler,
|
||||
shellTaskOrganizer);
|
||||
mRotationController =
|
||||
@@ -164,6 +164,14 @@ public class SplitScreenController implements SplitScreen,
|
||||
// Don't initialize the divider or anything until we get the default display.
|
||||
}
|
||||
|
||||
void onSplitScreenSupported() {
|
||||
// Set starting tile bounds based on middle target
|
||||
final WindowContainerTransaction tct = new WindowContainerTransaction();
|
||||
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
|
||||
mSplitLayout.resizeSplits(midPos, tct);
|
||||
mTaskOrganizer.applyTransaction(tct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSplitScreenSupported() {
|
||||
return mSplits.isSplitScreenSupported();
|
||||
@@ -196,11 +204,6 @@ public class SplitScreenController implements SplitScreen,
|
||||
}
|
||||
try {
|
||||
mSplits.init();
|
||||
// Set starting tile bounds based on middle target
|
||||
final WindowContainerTransaction tct = new WindowContainerTransaction();
|
||||
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
|
||||
mSplitLayout.resizeSplits(midPos, tct);
|
||||
mTaskOrganizer.applyTransaction(tct);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Failed to register docked stack listener", e);
|
||||
removeDivider();
|
||||
|
||||
@@ -23,25 +23,24 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_SPLIT_SCREEN;
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
|
||||
import static com.android.wm.shell.ShellTaskOrganizer.getWindowingMode;
|
||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
|
||||
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
|
||||
private static final String TAG = "SplitScreenTaskOrg";
|
||||
class SplitScreenTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
private static final String TAG = "SplitScreenTaskListener";
|
||||
private static final boolean DEBUG = SplitScreenController.DEBUG;
|
||||
|
||||
private final ShellTaskOrganizer mTaskOrganizer;
|
||||
@@ -58,20 +57,19 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
final SurfaceSession mSurfaceSession = new SurfaceSession();
|
||||
|
||||
SplitScreenTaskOrganizer(SplitScreenController splitScreenController,
|
||||
SplitScreenTaskListener(SplitScreenController splitScreenController,
|
||||
ShellTaskOrganizer shellTaskOrganizer) {
|
||||
mSplitScreenController = splitScreenController;
|
||||
mTaskOrganizer = shellTaskOrganizer;
|
||||
mTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_SPLIT_SCREEN);
|
||||
}
|
||||
|
||||
void init() throws RemoteException {
|
||||
void init() {
|
||||
synchronized (this) {
|
||||
try {
|
||||
mPrimary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
mSecondary = mTaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
mTaskOrganizer.createRootTask(
|
||||
DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, this);
|
||||
mTaskOrganizer.createRootTask(
|
||||
DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, this);
|
||||
} catch (Exception e) {
|
||||
// teardown to prevent callbacks
|
||||
mTaskOrganizer.removeListener(this);
|
||||
@@ -95,19 +93,26 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
|
||||
@Override
|
||||
public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
|
||||
synchronized (this) {
|
||||
if (mPrimary == null || mSecondary == null) {
|
||||
Log.w(TAG, "Received onTaskAppeared before creating root tasks " + taskInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (taskInfo.token.equals(mPrimary.token)) {
|
||||
final int winMode = getWindowingMode(taskInfo);
|
||||
if (winMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG,
|
||||
"%s onTaskAppeared Primary taskId=%d", TAG, taskInfo.taskId);
|
||||
mPrimary = taskInfo;
|
||||
mPrimarySurface = leash;
|
||||
} else if (taskInfo.token.equals(mSecondary.token)) {
|
||||
} else if (winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG,
|
||||
"%s onTaskAppeared Secondary taskId=%d", TAG, taskInfo.taskId);
|
||||
mSecondary = taskInfo;
|
||||
mSecondarySurface = leash;
|
||||
} else {
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared unknown taskId=%d winMode=%d",
|
||||
TAG, taskInfo.taskId, winMode);
|
||||
}
|
||||
|
||||
if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) {
|
||||
mSplitScreenSupported = true;
|
||||
mSplitScreenController.onSplitScreenSupported();
|
||||
ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared Supported", TAG);
|
||||
|
||||
// Initialize dim surfaces:
|
||||
mPrimaryDim = new SurfaceControl.Builder(mSurfaceSession)
|
||||
@@ -240,10 +245,13 @@ class SplitScreenTaskOrganizer implements ShellTaskOrganizer.TaskListener {
|
||||
final String innerPrefix = prefix + " ";
|
||||
final String childPrefix = innerPrefix + " ";
|
||||
pw.println(prefix + this);
|
||||
pw.println(innerPrefix + "mSplitScreenSupported=" + mSplitScreenSupported);
|
||||
if (mPrimary != null) pw.println(innerPrefix + "mPrimary.taskId=" + mPrimary.taskId);
|
||||
if (mSecondary != null) pw.println(innerPrefix + "mSecondary.taskId=" + mSecondary.taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_SPLIT_SCREEN);
|
||||
return TAG;
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class WindowManagerProxy {
|
||||
mTaskOrganizer = taskOrganizer;
|
||||
}
|
||||
|
||||
void dismissOrMaximizeDocked(final SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout,
|
||||
void dismissOrMaximizeDocked(final SplitScreenTaskListener tiles, SplitDisplayLayout layout,
|
||||
final boolean dismissOrMaximize) {
|
||||
mExecutor.execute(() -> applyDismissSplit(tiles, layout, dismissOrMaximize));
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class WindowManagerProxy {
|
||||
*
|
||||
* @return whether the home stack is resizable
|
||||
*/
|
||||
boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
|
||||
boolean applyEnterSplit(SplitScreenTaskListener tiles, SplitDisplayLayout layout) {
|
||||
// Set launchtile first so that any stack created after
|
||||
// getAllRootTaskInfos and before reparent (even if unlikely) are placed
|
||||
// correctly.
|
||||
@@ -242,7 +242,7 @@ class WindowManagerProxy {
|
||||
* split (thus resulting in the top of the secondary split becoming
|
||||
* fullscreen. {@code false} resolves the other way.
|
||||
*/
|
||||
void applyDismissSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout,
|
||||
void applyDismissSplit(SplitScreenTaskListener tiles, SplitDisplayLayout layout,
|
||||
boolean dismissOrMaximize) {
|
||||
// Set launch root first so that any task created after getChildContainers and
|
||||
// before reparent (pretty unlikely) are put into fullscreen.
|
||||
|
||||
@@ -795,6 +795,10 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
*/
|
||||
boolean mTaskAppearedSent;
|
||||
|
||||
// If the sending of the task appear signal should be deferred until this flag is set back to
|
||||
// false.
|
||||
private boolean mDeferTaskAppear;
|
||||
|
||||
/**
|
||||
* This task was created by the task organizer which has the following implementations.
|
||||
* <ul>
|
||||
@@ -807,14 +811,20 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
@VisibleForTesting
|
||||
boolean mCreatedByOrganizer;
|
||||
|
||||
// Tracking cookie for the creation of this task.
|
||||
IBinder mLaunchCookie;
|
||||
|
||||
/**
|
||||
* Don't use constructor directly. Use {@link TaskDisplayArea#createStackUnchecked()} instead.
|
||||
*/
|
||||
Task(ActivityTaskManagerService atmService, int id, int activityType,
|
||||
ActivityInfo info, Intent intent, boolean createdByOrganizer) {
|
||||
Task(ActivityTaskManagerService atmService, int id, int activityType, ActivityInfo info,
|
||||
Intent intent, boolean createdByOrganizer, boolean deferTaskAppear,
|
||||
IBinder launchCookie) {
|
||||
this(atmService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
|
||||
null /*taskDescription*/, null /*stack*/);
|
||||
mCreatedByOrganizer = createdByOrganizer;
|
||||
mLaunchCookie = launchCookie;
|
||||
mDeferTaskAppear = deferTaskAppear;
|
||||
setActivityType(activityType);
|
||||
}
|
||||
|
||||
@@ -4088,6 +4098,7 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
info.topActivityInfo = mReuseActivitiesReport.top != null
|
||||
? mReuseActivitiesReport.top.info
|
||||
: null;
|
||||
info.addLaunchCookie(mLaunchCookie);
|
||||
forAllActivities(r -> {
|
||||
info.addLaunchCookie(r.mLaunchCookie);
|
||||
});
|
||||
@@ -4857,6 +4868,13 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
return mHasBeenVisible;
|
||||
}
|
||||
|
||||
void setDeferTaskAppear(boolean deferTaskAppear) {
|
||||
mDeferTaskAppear = deferTaskAppear;
|
||||
if (!mDeferTaskAppear) {
|
||||
sendTaskAppeared();
|
||||
}
|
||||
}
|
||||
|
||||
/** In the case that these conditions are true, we want to send the Task to the organizer:
|
||||
* 1. An organizer has been set
|
||||
* 2. The Task was created by the organizer
|
||||
@@ -4871,6 +4889,10 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mDeferTaskAppear) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mCreatedByOrganizer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.app.WindowConfiguration;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.IBinder;
|
||||
import android.os.UserHandle;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
@@ -996,6 +997,13 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|
||||
false /* createdByOrganizer */);
|
||||
}
|
||||
|
||||
Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
|
||||
Intent intent, boolean createdByOrganizer) {
|
||||
return createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */,
|
||||
false /* createdByOrganizer */ , false /* deferTaskAppear */,
|
||||
null /* launchCookie */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a stack matching the input windowing mode and activity type on this display.
|
||||
*
|
||||
@@ -1013,10 +1021,14 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|
||||
* @param intent The intent that started this task.
|
||||
* @param createdByOrganizer @{code true} if this is created by task organizer, @{code false}
|
||||
* otherwise.
|
||||
* @param deferTaskAppear @{code true} if the task appeared signal should be deferred.
|
||||
* @param launchCookie Launch cookie used for tracking/association of the task we are
|
||||
* creating.
|
||||
* @return The newly created stack.
|
||||
*/
|
||||
Task createStack(int windowingMode, int activityType, boolean onTop, ActivityInfo info,
|
||||
Intent intent, boolean createdByOrganizer) {
|
||||
Intent intent, boolean createdByOrganizer, boolean deferTaskAppear,
|
||||
IBinder launchCookie) {
|
||||
if (activityType == ACTIVITY_TYPE_UNDEFINED && !createdByOrganizer) {
|
||||
// Can't have an undefined stack type yet...so re-map to standard. Anyone that wants
|
||||
// anything else should be passing it in anyways...except for the task organizer.
|
||||
@@ -1048,7 +1060,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|
||||
|
||||
final int stackId = getNextStackId();
|
||||
return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent,
|
||||
createdByOrganizer);
|
||||
createdByOrganizer, deferTaskAppear, launchCookie);
|
||||
}
|
||||
|
||||
/** @return the root task to create the next task in. */
|
||||
@@ -1078,8 +1090,9 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Task createStackUnchecked(int windowingMode, int activityType, int stackId,
|
||||
boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) {
|
||||
Task createStackUnchecked(int windowingMode, int activityType, int stackId, boolean onTop,
|
||||
ActivityInfo info, Intent intent, boolean createdByOrganizer, boolean deferTaskAppear,
|
||||
IBinder launchCookie) {
|
||||
if (windowingMode == WINDOWING_MODE_PINNED && activityType != ACTIVITY_TYPE_STANDARD) {
|
||||
throw new IllegalArgumentException("Stack with windowing mode cannot with non standard "
|
||||
+ "activity type.");
|
||||
@@ -1097,7 +1110,7 @@ final class TaskDisplayArea extends DisplayArea<Task> {
|
||||
}
|
||||
|
||||
final Task stack = new Task(mAtmService, stackId, activityType,
|
||||
info, intent, createdByOrganizer);
|
||||
info, intent, createdByOrganizer, deferTaskAppear, launchCookie);
|
||||
if (launchRootTask != null) {
|
||||
launchRootTask.addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);
|
||||
if (onTop) {
|
||||
|
||||
@@ -156,9 +156,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
void onTaskInfoChanged(Task task, ActivityManager.RunningTaskInfo taskInfo) {
|
||||
if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) {
|
||||
// Skip if the task has not yet received taskAppeared(), except for tasks created
|
||||
// by the organizer that don't receive that signal
|
||||
if (!task.mTaskAppearedSent) {
|
||||
// Skip if the task has not yet received taskAppeared().
|
||||
return;
|
||||
}
|
||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task info changed taskId=%d", task.mTaskId);
|
||||
@@ -179,9 +178,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
void onBackPressedOnTaskRoot(Task task) {
|
||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task back pressed on root taskId=%d",
|
||||
task.mTaskId);
|
||||
if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) {
|
||||
// Skip if the task has not yet received taskAppeared(), except for tasks created
|
||||
// by the organizer that don't receive that signal
|
||||
if (!task.mTaskAppearedSent) {
|
||||
// Skip if the task has not yet received taskAppeared().
|
||||
return;
|
||||
}
|
||||
if (!task.isOrganized()) {
|
||||
@@ -402,30 +400,39 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunningTaskInfo createRootTask(int displayId, int windowingMode) {
|
||||
public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
|
||||
enforceStackPermission("createRootTask()");
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mGlobalLock) {
|
||||
DisplayContent display = mService.mRootWindowContainer.getDisplayContent(displayId);
|
||||
if (display == null) {
|
||||
return null;
|
||||
ProtoLog.e(WM_DEBUG_WINDOW_ORGANIZER,
|
||||
"createRootTask unknown displayId=%d", displayId);
|
||||
return;
|
||||
}
|
||||
|
||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d",
|
||||
displayId, windowingMode);
|
||||
final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode,
|
||||
ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(),
|
||||
true /* createdByOrganizer */);
|
||||
RunningTaskInfo out = task.getTaskInfo();
|
||||
mLastSentTaskInfos.put(task, out);
|
||||
return out;
|
||||
createRootTask(display, windowingMode, launchCookie);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie) {
|
||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d",
|
||||
display.mDisplayId, windowingMode);
|
||||
// We want to defer the task appear signal until the task is fully created and attached to
|
||||
// to the hierarchy so that the complete starting configuration is in the task info we send
|
||||
// over to the organizer.
|
||||
final Task task = display.getDefaultTaskDisplayArea().createStack(windowingMode,
|
||||
ACTIVITY_TYPE_UNDEFINED, false /* onTop */, null /* info */, new Intent(),
|
||||
true /* createdByOrganizer */, true /* deferTaskAppear */, launchCookie);
|
||||
task.setDeferTaskAppear(false /* deferTaskAppear */);
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteRootTask(WindowContainerToken token) {
|
||||
enforceStackPermission("deleteRootTask()");
|
||||
|
||||
@@ -245,9 +245,8 @@ public class ActivityStackTests extends WindowTestsBase {
|
||||
.setStack(rootHomeTask)
|
||||
.setCreateTask(true)
|
||||
.build();
|
||||
final Task secondaryStack = (Task) WindowContainer.fromBinder(
|
||||
mAtm.mTaskOrganizerController.createRootTask(rootHomeTask.getDisplayId(),
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token.asBinder());
|
||||
final Task secondaryStack = mAtm.mTaskOrganizerController.createRootTask(
|
||||
rootHomeTask.getDisplayContent(), WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
|
||||
|
||||
rootHomeTask.reparent(secondaryStack, POSITION_TOP);
|
||||
assertEquals(secondaryStack, rootHomeTask.getParent());
|
||||
|
||||
@@ -1022,7 +1022,7 @@ public class ActivityStarterTests extends WindowTestsBase {
|
||||
assertThat(outActivity[0].inSplitScreenWindowingMode()).isFalse();
|
||||
|
||||
// Move activity to split-screen-primary stack and make sure it has the focus.
|
||||
TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayId());
|
||||
TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayContent());
|
||||
top.getRootTask().reparent(splitOrg.mPrimary, POSITION_BOTTOM);
|
||||
top.getRootTask().moveToFront("testWindowingModeOptionsLaunchAdjacent");
|
||||
|
||||
|
||||
@@ -479,21 +479,22 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testCreateDeleteRootTasks() {
|
||||
RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
Display.DEFAULT_DISPLAY,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
|
||||
|
||||
Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
dc, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
|
||||
RunningTaskInfo info1 = task1.getTaskInfo();
|
||||
assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
|
||||
info1.configuration.windowConfiguration.getWindowingMode());
|
||||
assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
|
||||
|
||||
RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
Display.DEFAULT_DISPLAY,
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
dc, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
|
||||
RunningTaskInfo info2 = task2.getTaskInfo();
|
||||
assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
|
||||
info2.configuration.windowConfiguration.getWindowingMode());
|
||||
assertEquals(ACTIVITY_TYPE_UNDEFINED, info2.topActivityType);
|
||||
|
||||
DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
|
||||
List<Task> infos = getTasksCreatedByOrganizer(dc);
|
||||
assertEquals(2, infos.size());
|
||||
|
||||
@@ -521,8 +522,9 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
||||
}
|
||||
};
|
||||
mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);
|
||||
RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
|
||||
RunningTaskInfo info1 = task.getTaskInfo();
|
||||
|
||||
final Task stack = createTaskStackOnDisplay(
|
||||
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, mDisplayContent);
|
||||
@@ -579,8 +581,9 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
||||
}
|
||||
};
|
||||
mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);
|
||||
RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
|
||||
RunningTaskInfo info1 = task.getTaskInfo();
|
||||
lastReportedTiles.clear();
|
||||
called[0] = false;
|
||||
|
||||
@@ -640,10 +643,13 @@ public class WindowOrganizerTests extends WindowTestsBase {
|
||||
}
|
||||
};
|
||||
mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(listener);
|
||||
RunningTaskInfo info1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
RunningTaskInfo info2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent.mDisplayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
|
||||
Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
|
||||
RunningTaskInfo info1 = task1.getTaskInfo();
|
||||
Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
|
||||
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
|
||||
RunningTaskInfo info2 = task2.getTaskInfo();
|
||||
|
||||
final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
|
||||
mDisplayContent.mDisplayId, null /* activityTypes */).size();
|
||||
|
||||
@@ -973,8 +973,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
final int taskId = mTaskId >= 0 ? mTaskId : mTaskDisplayArea.getNextStackId();
|
||||
if (mParentTask == null) {
|
||||
task = mTaskDisplayArea.createStackUnchecked(
|
||||
mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo,
|
||||
mIntent, false /* createdByOrganizer */);
|
||||
mWindowingMode, mActivityType, taskId, mOnTop, mActivityInfo, mIntent,
|
||||
false /* createdByOrganizer */, false /* deferTaskAppear */,
|
||||
null /* launchCookie */);
|
||||
} else {
|
||||
task = new Task(mSupervisor.mService, taskId, mActivityInfo,
|
||||
mIntent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
|
||||
@@ -1016,20 +1017,17 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
// moves everything to secondary. Most tests expect this since sysui usually does it.
|
||||
boolean mMoveToSecondaryOnEnter = true;
|
||||
int mDisplayId;
|
||||
TestSplitOrganizer(ActivityTaskManagerService service, int displayId) {
|
||||
TestSplitOrganizer(ActivityTaskManagerService service, DisplayContent display) {
|
||||
mService = service;
|
||||
mDisplayId = displayId;
|
||||
mDisplayId = display.mDisplayId;
|
||||
mService.mTaskOrganizerController.registerTaskOrganizer(this);
|
||||
WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
|
||||
displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
|
||||
mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
|
||||
WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
|
||||
displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
|
||||
mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
|
||||
mPrimary = mService.mTaskOrganizerController.createRootTask(
|
||||
display, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
|
||||
mSecondary = mService.mTaskOrganizerController.createRootTask(
|
||||
display, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);;
|
||||
}
|
||||
TestSplitOrganizer(ActivityTaskManagerService service) {
|
||||
this(service,
|
||||
service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId);
|
||||
this(service, service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay());
|
||||
}
|
||||
public void setMoveToSecondaryOnEnter(boolean move) {
|
||||
mMoveToSecondaryOnEnter = move;
|
||||
|
||||
Reference in New Issue
Block a user