Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1085,6 +1085,8 @@ public class SplitScreenController implements SplitDragPolicy.Starter, return "FULLSCREEN_REQUEST"; return "FULLSCREEN_REQUEST"; case EXIT_REASON_DRAG_TO_FULLSCREEN: case EXIT_REASON_DRAG_TO_FULLSCREEN: return "EXIT_REASON_DRAG_TO_FULLSCREEN"; return "EXIT_REASON_DRAG_TO_FULLSCREEN"; case EXIT_REASON_CHILD_TASK_ENTER_BUBBLE: return "CHILD_TASK_ENTER_BUBBLE"; default: default: return "unknown reason, reason int = " + exitReason; return "unknown reason, reason int = " + exitReason; } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +39 −4 Original line number Original line Diff line number Diff line Loading @@ -491,7 +491,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel); mWindowDecorViewModel, mBubbleController); } else { } else { mMainStage = new StageTaskListener( mMainStage = new StageTaskListener( mContext, mContext, Loading @@ -500,7 +501,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel, STAGE_TYPE_MAIN); mWindowDecorViewModel, STAGE_TYPE_MAIN, bubbleController); mSideStage = new StageTaskListener( mSideStage = new StageTaskListener( mContext, mContext, mTaskOrganizer, mTaskOrganizer, Loading @@ -508,7 +510,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel, STAGE_TYPE_SIDE); mWindowDecorViewModel, STAGE_TYPE_SIDE, mBubbleController); } } mTransitions = transitions; mTransitions = transitions; mDisplayController = displayController; mDisplayController = displayController; Loading Loading @@ -1747,7 +1750,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** /** * Starts a new transition to dismiss split. * Starts a new transition to dismiss split. */ */ private void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) { @VisibleForTesting void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) { if (!isSplitActive()) { if (!isSplitActive()) { return; return; } } Loading Loading @@ -2361,6 +2365,37 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } } } @Override public void onChildTaskMovedToBubble(StageTaskListener stage, int taskId) { if (stage.getChildCount() != 0) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onChildTaskMovedToBubble: task=%d in stage=%s moved to bubble, ignore, " + "childCount=%d", taskId, stageTypeToString(stage.getId()), stage.getChildCount()); return; } int stageToTop = STAGE_TYPE_UNDEFINED; if (enableFlexibleSplit()) { for (StageTaskListener activeStage : mStageOrderOperator.getActiveStages()) { // See if any other stage still has children if (activeStage.getChildCount() > 0) { stageToTop = activeStage.getId(); break; } } } else { final StageTaskListener remainingStage = stage == mMainStage ? mSideStage : mMainStage; if (remainingStage.getChildCount() > 0) { stageToTop = remainingStage.getId(); } } ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onChildTaskMovedToBubble: taskId=%d in stage=%s moved to bubble exit split " + "stageToTop=%s", taskId, stageTypeToString(stage.getId()), stageTypeToString(stageToTop)); dismissSplit(stageToTop, EXIT_REASON_CHILD_TASK_ENTER_BUBBLE); } private void updateRecentTasksSplitPair() { private void updateRecentTasksSplitPair() { // Preventing from single task update while processing recents. // Preventing from single task update while processing recents. if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) { if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt +8 −4 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context import com.android.internal.protolog.ProtoLog import com.android.internal.protolog.ProtoLog import com.android.launcher3.icons.IconProvider import com.android.launcher3.icons.IconProvider import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.protolog.ShellProtoLogGroup import com.android.wm.shell.protolog.ShellProtoLogGroup import com.android.wm.shell.shared.split.SplitScreenConstants import com.android.wm.shell.shared.split.SplitScreenConstants Loading Loading @@ -52,7 +53,8 @@ class StageOrderOperator ( stageCallbacks: StageTaskListener.StageListenerCallbacks, stageCallbacks: StageTaskListener.StageListenerCallbacks, syncQueue: SyncTransactionQueue, syncQueue: SyncTransactionQueue, iconProvider: IconProvider, iconProvider: IconProvider, windowDecorViewModel: Optional<WindowDecorViewModel> windowDecorViewModel: Optional<WindowDecorViewModel>, bubbleController: Optional<BubbleController>, ) { ) { private val MAX_STAGES = 3 private val MAX_STAGES = 3 Loading @@ -77,14 +79,16 @@ class StageOrderOperator ( init { init { for(i in 0 until MAX_STAGES) { for(i in 0 until MAX_STAGES) { allStages.add(StageTaskListener(context, allStages.add(StageTaskListener( context, taskOrganizer, taskOrganizer, displayId, displayId, stageCallbacks, stageCallbacks, syncQueue, syncQueue, iconProvider, iconProvider, windowDecorViewModel, windowDecorViewModel, stageIds[i]) stageIds[i], bubbleController) ) ) } } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFIN import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static com.android.wm.shell.Flags.enableFlexibleSplit; import static com.android.wm.shell.Flags.enableFlexibleSplit; import static com.android.wm.shell.Flags.fixExitSplitOnEnterBubble; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; Loading @@ -51,6 +52,7 @@ import com.android.internal.protolog.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.bubbles.BubbleController; import com.android.wm.shell.common.SurfaceUtils; import com.android.wm.shell.common.SurfaceUtils; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.split.SplitDecorManager; import com.android.wm.shell.common.split.SplitDecorManager; Loading Loading @@ -93,6 +95,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, boolean visible); boolean visible); /** Called when a child task vanished and is now in a bubble. */ void onChildTaskMovedToBubble(StageTaskListener stage, int taskId); /** Called when the root task on current display vanishes. */ /** Called when the root task on current display vanishes. */ void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); Loading @@ -106,6 +110,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; private final SyncTransactionQueue mSyncQueue; private final IconProvider mIconProvider; private final IconProvider mIconProvider; private final Optional<WindowDecorViewModel> mWindowDecorViewModel; private final Optional<WindowDecorViewModel> mWindowDecorViewModel; private final Optional<BubbleController> mBubbleController; /** Whether or not the root task has been created. */ /** Whether or not the root task has been created. */ boolean mHasRootTask = false; boolean mHasRootTask = false; Loading @@ -124,12 +129,14 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId, StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId, StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue, StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue, IconProvider iconProvider, IconProvider iconProvider, Optional<WindowDecorViewModel> windowDecorViewModel, int id) { Optional<WindowDecorViewModel> windowDecorViewModel, int id, Optional<BubbleController> bubbleController) { mContext = context; mContext = context; mCallbacks = callbacks; mCallbacks = callbacks; mSyncQueue = syncQueue; mSyncQueue = syncQueue; mIconProvider = iconProvider; mIconProvider = iconProvider; mWindowDecorViewModel = windowDecorViewModel; mWindowDecorViewModel = windowDecorViewModel; mBubbleController = bubbleController; taskOrganizer.createRootTask( taskOrganizer.createRootTask( new TaskOrganizer.CreateRootTaskRequest() new TaskOrganizer.CreateRootTaskRequest() .setName(stageTypeToString(id).toLowerCase()) .setName(stageTypeToString(id).toLowerCase()) Loading Loading @@ -334,8 +341,13 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { } else if (mChildrenTaskInfo.contains(taskId)) { } else if (mChildrenTaskInfo.contains(taskId)) { mChildrenTaskInfo.remove(taskId); mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); mChildrenLeashes.remove(taskId); if (fixExitSplitOnEnterBubble() && mBubbleController.map(c -> c.shouldBeAppBubble(taskInfo)).orElse(false)) { mCallbacks.onChildTaskMovedToBubble(this, taskId); } else { mCallbacks.onChildTaskStatusChanged(this, taskId, false /* present */, mCallbacks.onChildTaskStatusChanged(this, taskId, false /* present */, taskInfo.isVisible); taskInfo.isVisible); } } else { } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo + "\n mRootTaskInfo: " + mRootTaskInfo); + "\n mRootTaskInfo: " + mRootTaskInfo); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.bubbles.BubbleController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; Loading Loading @@ -138,6 +139,7 @@ public class SplitTransitionTests extends ShellTestCase { private FakeDesktopState mDesktopState; private FakeDesktopState mDesktopState; @Mock private IActivityTaskManager mActivityTaskManager; @Mock private IActivityTaskManager mActivityTaskManager; @Mock private MSDLPlayer mMSDLPlayer; @Mock private MSDLPlayer mMSDLPlayer; @Mock private BubbleController mBubbleController; private final TestShellExecutor mTestShellExecutor = new TestShellExecutor(); private final TestShellExecutor mTestShellExecutor = new TestShellExecutor(); private SplitLayout mSplitLayout; private SplitLayout mSplitLayout; private StageTaskListener mMainStage; private StageTaskListener mMainStage; Loading @@ -164,11 +166,13 @@ public class SplitTransitionTests extends ShellTestCase { mSplitLayout = SplitTestUtils.createMockSplitLayout(); mSplitLayout = SplitTestUtils.createMockSplitLayout(); mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( StageTaskListener.StageListenerCallbacks.class), mSyncQueue, StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN)); mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN, Optional.of(mBubbleController))); mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( StageTaskListener.StageListenerCallbacks.class), mSyncQueue, StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE)); mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE, Optional.of(mBubbleController))); mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY, mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1085,6 +1085,8 @@ public class SplitScreenController implements SplitDragPolicy.Starter, return "FULLSCREEN_REQUEST"; return "FULLSCREEN_REQUEST"; case EXIT_REASON_DRAG_TO_FULLSCREEN: case EXIT_REASON_DRAG_TO_FULLSCREEN: return "EXIT_REASON_DRAG_TO_FULLSCREEN"; return "EXIT_REASON_DRAG_TO_FULLSCREEN"; case EXIT_REASON_CHILD_TASK_ENTER_BUBBLE: return "CHILD_TASK_ENTER_BUBBLE"; default: default: return "unknown reason, reason int = " + exitReason; return "unknown reason, reason int = " + exitReason; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +39 −4 Original line number Original line Diff line number Diff line Loading @@ -491,7 +491,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel); mWindowDecorViewModel, mBubbleController); } else { } else { mMainStage = new StageTaskListener( mMainStage = new StageTaskListener( mContext, mContext, Loading @@ -500,7 +501,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel, STAGE_TYPE_MAIN); mWindowDecorViewModel, STAGE_TYPE_MAIN, bubbleController); mSideStage = new StageTaskListener( mSideStage = new StageTaskListener( mContext, mContext, mTaskOrganizer, mTaskOrganizer, Loading @@ -508,7 +510,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, this /*stageListenerCallbacks*/, this /*stageListenerCallbacks*/, mSyncQueue, mSyncQueue, iconProvider, iconProvider, mWindowDecorViewModel, STAGE_TYPE_SIDE); mWindowDecorViewModel, STAGE_TYPE_SIDE, mBubbleController); } } mTransitions = transitions; mTransitions = transitions; mDisplayController = displayController; mDisplayController = displayController; Loading Loading @@ -1747,7 +1750,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** /** * Starts a new transition to dismiss split. * Starts a new transition to dismiss split. */ */ private void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) { @VisibleForTesting void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) { if (!isSplitActive()) { if (!isSplitActive()) { return; return; } } Loading Loading @@ -2361,6 +2365,37 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } } } @Override public void onChildTaskMovedToBubble(StageTaskListener stage, int taskId) { if (stage.getChildCount() != 0) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onChildTaskMovedToBubble: task=%d in stage=%s moved to bubble, ignore, " + "childCount=%d", taskId, stageTypeToString(stage.getId()), stage.getChildCount()); return; } int stageToTop = STAGE_TYPE_UNDEFINED; if (enableFlexibleSplit()) { for (StageTaskListener activeStage : mStageOrderOperator.getActiveStages()) { // See if any other stage still has children if (activeStage.getChildCount() > 0) { stageToTop = activeStage.getId(); break; } } } else { final StageTaskListener remainingStage = stage == mMainStage ? mSideStage : mMainStage; if (remainingStage.getChildCount() > 0) { stageToTop = remainingStage.getId(); } } ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onChildTaskMovedToBubble: taskId=%d in stage=%s moved to bubble exit split " + "stageToTop=%s", taskId, stageTypeToString(stage.getId()), stageTypeToString(stageToTop)); dismissSplit(stageToTop, EXIT_REASON_CHILD_TASK_ENTER_BUBBLE); } private void updateRecentTasksSplitPair() { private void updateRecentTasksSplitPair() { // Preventing from single task update while processing recents. // Preventing from single task update while processing recents. if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) { if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt +8 −4 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Context import com.android.internal.protolog.ProtoLog import com.android.internal.protolog.ProtoLog import com.android.launcher3.icons.IconProvider import com.android.launcher3.icons.IconProvider import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.protolog.ShellProtoLogGroup import com.android.wm.shell.protolog.ShellProtoLogGroup import com.android.wm.shell.shared.split.SplitScreenConstants import com.android.wm.shell.shared.split.SplitScreenConstants Loading Loading @@ -52,7 +53,8 @@ class StageOrderOperator ( stageCallbacks: StageTaskListener.StageListenerCallbacks, stageCallbacks: StageTaskListener.StageListenerCallbacks, syncQueue: SyncTransactionQueue, syncQueue: SyncTransactionQueue, iconProvider: IconProvider, iconProvider: IconProvider, windowDecorViewModel: Optional<WindowDecorViewModel> windowDecorViewModel: Optional<WindowDecorViewModel>, bubbleController: Optional<BubbleController>, ) { ) { private val MAX_STAGES = 3 private val MAX_STAGES = 3 Loading @@ -77,14 +79,16 @@ class StageOrderOperator ( init { init { for(i in 0 until MAX_STAGES) { for(i in 0 until MAX_STAGES) { allStages.add(StageTaskListener(context, allStages.add(StageTaskListener( context, taskOrganizer, taskOrganizer, displayId, displayId, stageCallbacks, stageCallbacks, syncQueue, syncQueue, iconProvider, iconProvider, windowDecorViewModel, windowDecorViewModel, stageIds[i]) stageIds[i], bubbleController) ) ) } } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFIN import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static com.android.wm.shell.Flags.enableFlexibleSplit; import static com.android.wm.shell.Flags.enableFlexibleSplit; import static com.android.wm.shell.Flags.fixExitSplitOnEnterBubble; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; Loading @@ -51,6 +52,7 @@ import com.android.internal.protolog.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.bubbles.BubbleController; import com.android.wm.shell.common.SurfaceUtils; import com.android.wm.shell.common.SurfaceUtils; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.split.SplitDecorManager; import com.android.wm.shell.common.split.SplitDecorManager; Loading Loading @@ -93,6 +95,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present, boolean visible); boolean visible); /** Called when a child task vanished and is now in a bubble. */ void onChildTaskMovedToBubble(StageTaskListener stage, int taskId); /** Called when the root task on current display vanishes. */ /** Called when the root task on current display vanishes. */ void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo); Loading @@ -106,6 +110,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; private final SyncTransactionQueue mSyncQueue; private final IconProvider mIconProvider; private final IconProvider mIconProvider; private final Optional<WindowDecorViewModel> mWindowDecorViewModel; private final Optional<WindowDecorViewModel> mWindowDecorViewModel; private final Optional<BubbleController> mBubbleController; /** Whether or not the root task has been created. */ /** Whether or not the root task has been created. */ boolean mHasRootTask = false; boolean mHasRootTask = false; Loading @@ -124,12 +129,14 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId, StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId, StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue, StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue, IconProvider iconProvider, IconProvider iconProvider, Optional<WindowDecorViewModel> windowDecorViewModel, int id) { Optional<WindowDecorViewModel> windowDecorViewModel, int id, Optional<BubbleController> bubbleController) { mContext = context; mContext = context; mCallbacks = callbacks; mCallbacks = callbacks; mSyncQueue = syncQueue; mSyncQueue = syncQueue; mIconProvider = iconProvider; mIconProvider = iconProvider; mWindowDecorViewModel = windowDecorViewModel; mWindowDecorViewModel = windowDecorViewModel; mBubbleController = bubbleController; taskOrganizer.createRootTask( taskOrganizer.createRootTask( new TaskOrganizer.CreateRootTaskRequest() new TaskOrganizer.CreateRootTaskRequest() .setName(stageTypeToString(id).toLowerCase()) .setName(stageTypeToString(id).toLowerCase()) Loading Loading @@ -334,8 +341,13 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener { } else if (mChildrenTaskInfo.contains(taskId)) { } else if (mChildrenTaskInfo.contains(taskId)) { mChildrenTaskInfo.remove(taskId); mChildrenTaskInfo.remove(taskId); mChildrenLeashes.remove(taskId); mChildrenLeashes.remove(taskId); if (fixExitSplitOnEnterBubble() && mBubbleController.map(c -> c.shouldBeAppBubble(taskInfo)).orElse(false)) { mCallbacks.onChildTaskMovedToBubble(this, taskId); } else { mCallbacks.onChildTaskStatusChanged(this, taskId, false /* present */, mCallbacks.onChildTaskStatusChanged(this, taskId, false /* present */, taskInfo.isVisible); taskInfo.isVisible); } } else { } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo + "\n mRootTaskInfo: " + mRootTaskInfo); + "\n mRootTaskInfo: " + mRootTaskInfo); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.bubbles.BubbleController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController; Loading Loading @@ -138,6 +139,7 @@ public class SplitTransitionTests extends ShellTestCase { private FakeDesktopState mDesktopState; private FakeDesktopState mDesktopState; @Mock private IActivityTaskManager mActivityTaskManager; @Mock private IActivityTaskManager mActivityTaskManager; @Mock private MSDLPlayer mMSDLPlayer; @Mock private MSDLPlayer mMSDLPlayer; @Mock private BubbleController mBubbleController; private final TestShellExecutor mTestShellExecutor = new TestShellExecutor(); private final TestShellExecutor mTestShellExecutor = new TestShellExecutor(); private SplitLayout mSplitLayout; private SplitLayout mSplitLayout; private StageTaskListener mMainStage; private StageTaskListener mMainStage; Loading @@ -164,11 +166,13 @@ public class SplitTransitionTests extends ShellTestCase { mSplitLayout = SplitTestUtils.createMockSplitLayout(); mSplitLayout = SplitTestUtils.createMockSplitLayout(); mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( StageTaskListener.StageListenerCallbacks.class), mSyncQueue, StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN)); mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN, Optional.of(mBubbleController))); mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock( StageTaskListener.StageListenerCallbacks.class), mSyncQueue, StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE)); mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE, Optional.of(mBubbleController))); mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface()); mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY, mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController, Loading