android T split screen process

overview

insert image description here
insert image description here
order before split screen

  Task display areas in top down Z order:
    TaskDisplayArea DefaultTaskDisplayArea
      mPreferredTopFocusableRootTask=Task{
    
    919dc1b #1 type=home ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=1}
      mLastFocusedRootTask=Task{
    
    919dc1b #1 type=home ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=1}
      Application tokens in top down Z order:
      * Task{
    
    919dc1b #1 type=home ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=1}
        bounds=[0,0][1080,2520]
        * Task{
    
    95cd9f8 #2 type=home I=com.miui.home/.launcher.Launcher U=0 rootTaskId=1 visible=true visibleRequested=true mode=fullscreen translucent=false sz=1}
          bounds=[0,0][1080,2520]
          * ActivityRecord{
    
    23a7bec u0 com.miui.home/.launcher.Launcher} t2}
      * Task{
    
    e49cf5a #27 type=standard A=10219:com.miui.weather2 U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
        bounds=[0,0][1080,2520]
        * ActivityRecord{
    
    4788499 u0 com.miui.weather2/.ActivityWeatherMain} t27}
      * Task{
    
    ec94c1a #38 type=undefined ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0}
        bounds=[0,0][1080,2520]
      * Task{
    
    a07962f #25 type=standard A=10070:android.task.mms U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
        bounds=[0,0][1080,2520]
        * ActivityRecord{
    
    43f400e u0 com.android.mms/.ui.MmsTabActivity} t25}
    // 分屏的Task位于TaskDisplayArea的最底部
      * Task{
    
    bcbb9ca #39 type=standard ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=2}
        bounds=[0,0][1080,2520]
        * Task{
    
    495d73b #41 type=standard ?? U=0 rootTaskId=39 visible=false visibleRequested=false mode=multi-window translucent=true sz=0}
          bounds=[0,1317][1080,2520]
        * Task{
    
    65e6135 #40 type=undefined ?? U=0 rootTaskId=39 visible=false visibleRequested=false mode=multi-window translucent=true sz=0}
          bounds=[0,0][1080,1289]

order in split screen

  Task display areas in top down Z order:
    TaskDisplayArea DefaultTaskDisplayArea
      mPreferredTopFocusableRootTask=Task{
    
    f555c62 #4 type=standard ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}
      mLastFocusedRootTask=Task{
    
    f555c62 #4 type=standard ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}
      Application tokens in top down Z order:
      // reorder分屏相关Task到TaskDisplayArea顶部
      * Task{
    
    f555c62 #4 type=standard ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}
        bounds=[0,0][1080,2520]
        * Task{
    
    f4a61f3 #6 type=undefined ?? U=0 rootTaskId=4 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
          bounds=[0,1295][1080,2520]
          * Task{
    
    9b3720c #80 type=standard A=10213:com.miui.notes U=0 rootTaskId=4 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
            bounds=[0,1295][1080,2520]
            * ActivityRecord{
    
    2ab7e0 u0 com.miui.notes/.ui.NotesListActivity} t80}
        * Task{
    
    3c50f2d #5 type=standard ?? U=0 rootTaskId=4 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
          bounds=[0,0][1080,1267]
          * Task{
    
    27d1129 #78 type=undefined A=10003:com.miui.gallery.home U=0 rootTaskId=4 visible=true visibleRequested=true mode=multi-window translucent=false sz=2}
            bounds=[0,0][1080,1267]
            * ActivityRecord{
    
    c63706 u0 com.miui.gallery/.activity.GallerySettingsActivity} t78}
            * ActivityRecord{
    
    1435ba u0 com.miui.gallery/.activity.HomePageActivity} t78}
      * Task{
    
    a48f388 #1 type=home ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
        bounds=[0,0][1080,2520]
        * Task{
    
    e676dd2 #2 type=home I=com.miui.home/.launcher.Launcher U=0 rootTaskId=1 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
          bounds=[0,0][1080,2520]
          * ActivityRecord{
    
    3faca81 u0 com.miui.home/.launcher.Launcher} t2}
      * Task{
    
    ad9de1e #3 type=undefined ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0}
        bounds=[0,0][1080,2520]

enter split screen

systemui process

The split screen on android T is that after the split screen is confirmed, the desktop process calls the startTasksWithLegacyTransition method of com.android.wm.shell.splitscreen.SplitScreenController.ISplitScreenImpl under the wm shell of the systemui process to start the split screen process.

    /**
     * The interface for calls from outside the host process.
     */
    @BinderThread
    private static class ISplitScreenImpl extends ISplitScreen.Stub {
    
    
        ......
        @Override
        public void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions,
                int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
                float splitRatio, RemoteAnimationAdapter adapter) {
    
    
            // binder 线程post 到主线程的executor去执行
            executeRemoteCallWithTaskPermission(mController, "startTasks",
                    (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition(
                            mainTaskId, mainOptions, sideTaskId, sideOptions, sidePosition,
                            splitRatio, adapter));
        }

system server process

When entering split screen, the HierarchyOp list of WindowContainerTransaction contains three elements: reorder, startTask, startTask
insert image description here

    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
            @Nullable Transition transition, @NonNull CallerInfo caller,
            @Nullable Transition finishTransition) {
    
    
            ......
            // Hierarchy changes
            final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
            final int hopSize = hops.size();
            if (hopSize > 0) {
    
    
                final boolean isInLockTaskMode = mService.isInLockTaskMode();
                for (int i = 0; i < hopSize; ++i) {
    
    
                    effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
                            isInLockTaskMode, caller, t.getErrorCallbackToken(),
                            t.getTaskFragmentOrganizer(), finishTransition);
                }
            }
           ......
    }

insert image description here

exit split screen

systemui process

insert image description here

system server process

When exiting the split screen, the HierarchyOp list of WindowContainerTransaction also contains three elements: childrenTasksReparent, childrenTasksReparent, reorder (fullcscreen task at the outermost layer of the split screen)
insert image description here

{
    
    ChildrenTasksReparent: from=RemoteToken{
    
    6206d89 Task{
    
    495d73b #41 type=standard ?? U=0 rootTaskId=39 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}} to=null mToTop=false mReparentTopOnly=false mWindowingMode=[1, 0, 6] mActivityType=[1]}
{
    
    ChildrenTasksReparent: from=RemoteToken{
    
    1d0a090 Task{
    
    65e6135 #40 type=undefined ?? U=0 rootTaskId=39 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}} to=null mToTop=true mReparentTopOnly=false mWindowingMode=[1, 0, 6] mActivityType=[1]}
{
    
    reorder: RemoteToken{
    
    aae4b1a Task{
    
    bcbb9ca #39 type=standard ?? U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}} to bottom}

insert image description here

    private int reparentChildrenTasksHierarchyOp(WindowContainerTransaction.HierarchyOp hop,
            @Nullable Transition transition, int syncId) {
    
    
        // 一般为分屏的上下屏Task,mode为multi-window
        WindowContainer<?> currentParent = hop.getContainer() != null
                ? WindowContainer.fromBinder(hop.getContainer()) : null;
        // 这里一般为null
        WindowContainer newParent = hop.getNewParent() != null
                ? WindowContainer.fromBinder(hop.getNewParent()) : null;
        if (currentParent == null && newParent == null) {
    
    
            throw new IllegalArgumentException("reparentChildrenTasksHierarchyOp: " + hop);
        } else if (currentParent == null) {
    
    
            currentParent = newParent.asTask().getDisplayContent().getDefaultTaskDisplayArea();
        } else if (newParent == null) {
    
    
            // newParent赋值为TaskDisplayArea
            newParent = currentParent.asTask().getDisplayContent().getDefaultTaskDisplayArea();
        }

       ......

        // We want to collect the tasks first before re-parenting to avoid array shifting on us.
        final ArrayList<Task> tasksToReparent = new ArrayList<>();

        currentParent.forAllTasks(task -> {
    
    
            Slog.i(TAG, " Processing task=" + task);
            final boolean reparent;
            if (task.mCreatedByOrganizer || task.getParent() != finalCurrentParent) {
    
    
                // We only care about non-organized task that are direct children of the thing we
                // are reparenting from.
                return false;
            }
            if (newParentInMultiWindow && !task.supportsMultiWindowInDisplayArea(newParentTda)) {
    
    
                Slog.e(TAG, "reparentChildrenTasksHierarchyOp non-resizeable task to multi window,"
                        + " task=" + task);
                return false;
            }
            if (!ArrayUtils.contains(hop.getActivityTypes(), task.getActivityType())
                    || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
    
    
                return false;
            }

            if (hop.getToTop()) {
    
    
                tasksToReparent.add(0, task);
            } else {
    
    
                tasksToReparent.add(task);
            }
            return hop.getReparentTopOnly() && tasksToReparent.size() == 1;
        });

        final int count = tasksToReparent.size();
        for (int i = 0; i < count; ++i) {
    
    
            final Task task = tasksToReparent.get(i);
            if (syncId >= 0) {
    
    
                addToSyncSet(syncId, task);
            }
            if (transition != null) transition.collect(task);
        	// 执行reparent操作
            if (newParent instanceof TaskDisplayArea) {
    
    
                // For now, reparenting to display area is different from other reparents...
                task.reparent((TaskDisplayArea) newParent, hop.getToTop());
            } else {
    
    
                task.reparent((Task) newParent,
                        hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
                        false /*moveParents*/, "processChildrenTaskReparentHierarchyOp");
            }
        }

        if (transition != null) transition.collect(newParent);

        return TRANSACT_EFFECTS_LIFECYCLE;
    }

Guess you like

Origin blog.csdn.net/xiaoyantan/article/details/127096863