android T分屏流程

  • Post author:
  • Post category:其他




概览

在这里插入图片描述

在这里插入图片描述

分屏前的order

  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

  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]



进入分屏



systemui 进程

android T上的分屏是在分屏下屏确定后桌面进程调用位于systemui进程的wm shell下的com.android.wm.shell.splitscreen.SplitScreenController.ISplitScreenImpl的startTasksWithLegacyTransition方法去开启分屏流程。

    /**
     * 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进程

进入分屏时WindowContainerTransaction的HierarchyOp列表包含三个元素:reorder、startTask、startTask

在这里插入图片描述

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

在这里插入图片描述



退出分屏



systemui进程

在这里插入图片描述



system server进程

退出分屏时WindowContainerTransaction的HierarchyOp列表也包含三个元素:childrenTasksReparent、childrenTasksReparent、reorder(分屏最外层的fullcscreen task)

在这里插入图片描述

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

在这里插入图片描述

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



版权声明:本文为xiaoyantan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。