Android 13 split screen source code analysis of the dividing line dragging process

Hi, the previous section has analyzed the start-up process of the split screen, and this section begins to introduce the process of dragging the dividing line during the use of the split screen.

1. The dragging part of the dividing line

B station free video tutorial explanation:
https://www.bilibili.com/video/BV1wj411o7A9/Look
insert image description here
at the onTouch of the DividerView of the dragged dividing line

    public boolean onTouch(View v, MotionEvent event) {
    
    
        if (mSplitLayout == null || !mInteractive) {
    
    
            return false;
        }

        if (mDoubleTapDetector.onTouchEvent(event)) {
    
    
            return true;
        }

        // Convert to use screen-based coordinates to prevent lost track of motion events while
        // moving divider bar and calculating dragging velocity.
        event.setLocation(event.getRawX(), event.getRawY());
        final int action = event.getAction() & MotionEvent.ACTION_MASK;
        final boolean isLandscape = isLandscape();
        final int touchPos = (int) (isLandscape ? event.getX() : event.getY());
        switch (action) {
    
    
            case MotionEvent.ACTION_DOWN:
                mVelocityTracker = VelocityTracker.obtain();
                mVelocityTracker.addMovement(event);
                setTouching();
                mStartPos = touchPos;
                mMoving = false;
                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.addMovement(event);
                if (!mMoving && Math.abs(touchPos - mStartPos) > mTouchSlop) {
    
    
                    mStartPos = touchPos;
                    mMoving = true;
                }
                if (mMoving) {
    
    
                    final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                    mSplitLayout.updateDivideBounds(position);//最重要的拖动方法
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                releaseTouching();
                if (!mMoving) break;

                mVelocityTracker.addMovement(event);
                mVelocityTracker.computeCurrentVelocity(1000 /* units */);
                final float velocity = isLandscape
                        ? mVelocityTracker.getXVelocity()
                        : mVelocityTracker.getYVelocity();
                final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                final DividerSnapAlgorithm.SnapTarget snapTarget =
                        mSplitLayout.findSnapTarget(position, velocity, false /* hardDismiss */);
                mSplitLayout.snapToTarget(position, snapTarget);//松手后要进行动画,DividerView自动到某个区域
                mMoving = false;
                break;
        }

        return true;
    }

Here we focus on the mSplitLayout.updateDivideBounds(position) method:

    /**
     * Updates bounds with the passing position. Usually used to update recording bounds while
     * performing animation or dragging divider bar to resize the splits.
     */
    void updateDivideBounds(int position) {
    
    
        updateBounds(position);//更新一下bound区域
        mSplitLayoutHandler.onLayoutSizeChanging(this);
        //会调用对应的onLayoutSizeChanging方法来负责通知size变化了
    }

   @Override
    public void onLayoutSizeChanging(SplitLayout layout) {
    
    
        final SurfaceControl.Transaction t = mTransactionPool.acquire();
        t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
        setResizingSplits(true /* resizing */);
        updateSurfaceBounds(layout, t, true /* applyResizingOffset */);//会把对应的DividerView进行坐标更新,实现跟手
        mMainStage.onResizing(getMainStageBounds(), t);//通知主屏幕,告知有size变化,如果bounds变大则显示icon+背景,否则显示原来内容,并控制内容的区域跟随divideriew位置
        mSideStage.onResizing(getSideStageBounds(), t);//通知次屏幕,告知有size变化,如果bounds变大则显示icon+背景,否则显示原来内容,并控制内容的区域跟随divideriew位置
        t.apply();
        mTransactionPool.release(t);
    }
       void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,
            boolean applyResizingOffset) {
    
    
        final StageTaskListener topLeftStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
        final StageTaskListener bottomRightStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
                //这里关键调用了applySurfaceChanges
        (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash,
                bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer,
                applyResizingOffset);
    }

Let's take a look at the applySurfaceChanges method:

public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
            SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2,
            boolean applyResizingOffset) {
    
    
        final SurfaceControl dividerLeash = getDividerLeash();
        if (dividerLeash != null) {
    
    
            mTempRect.set(getRefDividerBounds());
            t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
            //这里是设置DeviderView进行位置设置
            // Resets layer of divider bar to make sure it is always on top.
            t.setLayer(dividerLeash, Integer.MAX_VALUE);
        }
        mTempRect.set(getRefBounds1());
        t.setPosition(leash1, mTempRect.left, mTempRect.top)//设置上下分屏的位置和裁减
                .setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
        mTempRect.set(getRefBounds2());
        t.setPosition(leash2, mTempRect.left, mTempRect.top)
                .setWindowCrop(leash2, mTempRect.width(), mTempRect.height());

        if (mImePositionProcessor.adjustSurfaceLayoutForIme(
                t, dividerLeash, leash1, leash2, dimLayer1, dimLayer2)) {
    
    
            return;
        }

        mSurfaceEffectPolicy.adjustDimSurface(t, dimLayer1, dimLayer2);//进行对应的特效显示,拉到底部或之顶部进行灰度提示
        if (applyResizingOffset) {
    
    
            mSurfaceEffectPolicy.adjustRootSurface(t, leash1, leash2);
        }
    }

Next, look at the mMainStage.onResizing method:


 /** Showing resizing hint. */
    public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
            SurfaceControl.Transaction t) {
    
    
   //省略
   //这里本质就是判断是否该区域有变大,如果有变大则变成ICON+背景,另一个屏则保持原样,因为show是为false
        final boolean show =
                newBounds.width() > mBounds.width() || newBounds.height() > mBounds.height();
 			//省略
        t.setPosition(mIconLeash,
                newBounds.width() / 2 - mIconSize / 2,
                newBounds.height() / 2 - mIconSize / 2);

        if (animate) {
    
    //启动相关显示的动画
            startFadeAnimation(show, false /* isResized */);
            mShown = show;
        }
    }

insert image description here

Drag the DividerView to move the coordinates to set the stack


setPosition:2964, SurfaceControl$Transaction (android.view)
applySurfaceChanges:508, SplitLayout (com.android.wm.shell.common.split)
updateSurfaceBounds:1286, StageCoordinator (com.android.wm.shell.splitscreen)
onLayoutSizeChanging:1233, StageCoordinator (com.android.wm.shell.splitscreen)
updateDivideBounds:358, SplitLayout (com.android.wm.shell.common.split)
onTouch:298, DividerView (com.android.wm.shell.common.split)
dispatchTouchEvent:15000, View (android.view)
dispatchTransformedTouchEvent:3115, ViewGroup (android.view)
dispatchTouchEvent:2788, ViewGroup (android.view)
dispatchPointerEvent:15263, View (android.view)
processPointerEvent:6548, ViewRootImpl$ViewPostImeInputStage (android.view)
onProcess:6348, ViewRootImpl$ViewPostImeInputStage (android.view)
deliver:5804, ViewRootImpl$InputStage (android.view)
onDeliverToNext:5861, ViewRootImpl$InputStage (android.view)
forward:5827, ViewRootImpl$InputStage (android.view)
forward:5992, ViewRootImpl$AsyncInputStage (android.view)
apply:5835, ViewRootImpl$InputStage (android.view)
apply:6049, ViewRootImpl$AsyncInputStage (android.view)
deliver:5808, ViewRootImpl$InputStage (android.view)
onDeliverToNext:5861, ViewRootImpl$InputStage (android.view)
forward:5827, ViewRootImpl$InputStage (android.view)
apply:5835, ViewRootImpl$InputStage (android.view)
deliver:5808, ViewRootImpl$InputStage (android.view)
deliverInputEvent:8857, ViewRootImpl (android.view)
doProcessInputEvents:8808, ViewRootImpl (android.view)
enqueueInputEvent:8777, ViewRootImpl (android.view)
onInputEvent:8980, ViewRootImpl$WindowInputEventReceiver (android.view)
dispatchInputEvent:267, InputEventReceiver (android.view)
nativeConsumeBatchedInputEvents:-1, InputEventReceiver (android.view)
consumeBatchedInputEvents:247, InputEventReceiver (android.view)
doConsumeBatchedInput:8937, ViewRootImpl (android.view)
run:9071, ViewRootImpl$ConsumeBatchedInputRunnable (android.view)
run:1231, Choreographer$CallbackRecord (android.view)
run:1239, Choreographer$CallbackRecord (android.view)
doCallbacks:899, Choreographer (android.view)
doFrame:824, Choreographer (android.view)
run:1214, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7897, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

2. The moving animation after letting go and the area setting of the Task

As already known above, it is mainly executed by mSplitLayout.snapToTarget(position, snapTarget) after letting go:

  /**
     * Sets new divide position and updates bounds correspondingly. Notifies listener if the new
     * target indicates dismissing split.
     */
    public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
    
    
        switch (snapTarget.flag) {
    
    
            case FLAG_DISMISS_START:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */));
                break;
            case FLAG_DISMISS_END:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */));
                break;
            default:
                flingDividePosition(currentPosition, snapTarget.position,
                        () -> setDividePosition(snapTarget.position, true /* applyLayoutChange */));
                break;
        }
    }

Let’s talk about FLAG_DISMISS_START and FLAG_DISMISS_END here:
FLAG_DISMISS_START: means that the DividerView slides up to the top, resulting in the exit of the upper split screen, as shown in the figure below
insert image description here

FLAG_DISMISS_END: ​​Represents sliding down until the next split screen exits the scene

You can see that there are many situations, but they will all call flingDividePosition, but the final callback method is different. Here we generally use the default situation:

 @VisibleForTesting
    void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
    
    
        if (from == to) {
    
    
            // No animation run, still callback to stop resizing.
            mSplitLayoutHandler.onLayoutSizeChanged(this);
            return;
        }
        InteractionJankMonitorUtils.beginTracing(InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE,
                mSplitWindowManager.getDividerView(), "Divider fling");
        ValueAnimator animator = ValueAnimator
                .ofInt(from, to)
                .setDuration(250);//开始设置动画,一个from一个to作为开始和截至地方
        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        animator.addUpdateListener(
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
        animator.addListener(new AnimatorListenerAdapter() {
    
    
            @Override
            public void onAnimationEnd(Animator animation) {
    
    
            //动画结束以后的最重要的操作,需要真正的windowcontainer的bounds进行操作了
                if (flingFinishedCallback != null) {
    
    
                    flingFinishedCallback.run();//执行传递进来的那个runable
                }
                InteractionJankMonitorUtils.endTracing(
                        InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
    
    
                setDividePosition(to, true /* applyLayoutChange */);
            }
        });
        animator.start();
    }

The key point here is to call the setDividePosition method after the animation execution is completed.

  void setDividePosition(int position, boolean applyLayoutChange) {
    
    
        mDividePosition = position;
        updateBounds(mDividePosition);
        if (applyLayoutChange) {
    
    
            mSplitLayoutHandler.onLayoutSizeChanged(this);
        }
    }

This setDividePosition has been explained before https://blog.csdn.net/learnframework/article/details/130944230
and finally the corresponding bounds will be set to the task of the systemserver

3. The exit principle of systemserver

Look at the calling situation on the systemui side:

frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java

 private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop,
            WindowContainerTransaction wct, @ExitReason int exitReason) {
    
    
       //省略
        final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP;
        mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop);//移除对应的sidestate下面task节点,其实本质就是把子节点进行对应的reparent到新的父亲
        mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);//其实和上面的removeAllTask类似,都是对task进行reparent操作,不能再继续挂载在分屏的节点了
        
        //对分屏的总节点进行对应的reorder,放到后面了,不能到最前啦
        wct.reorder(mRootTaskInfo.token, false /* onTop */);
        mTaskOrganizer.applyTransaction(wct);
        mSyncQueue.runInSync(t -> {
    
    
            setResizingSplits(false /* resizing */);
            t.setWindowCrop(mMainStage.mRootLeash, null)
                    .setWindowCrop(mSideStage.mRootLeash, null);
            setDividerVisibility(false, t);
        });
//省略
    }

Take a look at the corresponding mSideStage.removeAllTasks method:

   boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
    
    
        if (mChildrenTaskInfo.size() == 0) return false;
        wct.reparentTasks(
                mRootTaskInfo.token,
                null /* newParent */,
                CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
                CONTROLLED_ACTIVITY_TYPES,
                toTop);
        return true;
    }

Called reparentTasks, let's take a look at reparentTasks
frameworks/base/core/java/android/window/WindowContainerTransaction.java

public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent,
            @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes,
            @Nullable int[] activityTypes, boolean onTop, boolean reparentTopOnly) {
    
    
        mHierarchyOps.add(HierarchyOp.createForChildrenTasksReparent(
                currentParent != null ? currentParent.asBinder() : null,
                newParent != null ? newParent.asBinder() : null,
                windowingModes,
                activityTypes,
                onTop,
                reparentTopOnly));
        return this;
    }

//创建对应HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT的HierarchyOp
        public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent,
                IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop,
                boolean reparentTopOnly) {
    
    
            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT)
                    .setContainer(currentParent)
                    .setReparentContainer(newParent)
                    .setWindowingModes(windowingModes)
                    .setActivityTypes(activityTypes)
                    .setToTop(onTop)
                    .setReparentTopOnly(reparentTopOnly)
                    .build();
        }

At this point, the exit operation of the systemui part is completed

Look at the calls on the systemserver side:

frameworks/base/services/core/java/com/android/server/wm/WindowOrganizerController.java

 private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
            int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
            @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken,
            @Nullable ITaskFragmentOrganizer organizer, @Nullable Transition finishTransition) {
    
    
            //省略
               switch (type) {
    
    
            case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: {
    
    
            //核心方法
                effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
                break;
            }
            //省略
            }   

The core method reparentChildrenTasksHierarchyOp is called here


 private int reparentChildrenTasksHierarchyOp(WindowContainerTransaction.HierarchyOp hop,
            @Nullable Transition transition, int syncId) {
    
    
        WindowContainer<?> currentParent = hop.getContainer() != null
                ? WindowContainer.fromBinder(hop.getContainer()) : null;
        WindowContainer newParent = hop.getNewParent() != null
                ? WindowContainer.fromBinder(hop.getNewParent()) : null;
        if (currentParent == null && newParent == null) {
    
    
           //省略
        } else if (newParent == null) {
    
    //这里传递为null,所以给予没人的parent为DefaultTaskDisplayArea
            newParent = currentParent.asTask().getDisplayContent().getDefaultTaskDisplayArea();
        }

       //省略
        final ArrayList<Task> tasksToReparent = new ArrayList<>();
//对当前的task节点下面所有children进行遍历
        currentParent.forAllTasks(task -> {
    
    
            final boolean reparent;
            //注意这里的话可能activitytype和windowmode不支持,就要直接返回不会放入tasksToReparent
            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);
          //省略
          //刚好这里newParent就是TaskDisplayArea,即直接把原理挂在上下分屏的task挂到TaskDisplayArea下面
            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");
            }
        }
        return TRANSACT_EFFECTS_LIFECYCLE;
    }

In this way, the entire split screen ends and the core process is completed, and the rest must be related to resumeToActivity and ensureVisibleActivity to trigger changes in the life cycle

Supplement the initialization process of the relevant position of the relevant dividing line. There are a total of 5 positions, the top, the bottom, the middle, the upper half, and the lower half. The creation process is as follows:

07-15 16:51:55.253   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:301)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.253   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.253   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.253   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 810
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.maybeAddTarget(DividerSnapAlgorithm.java:362)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:323)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 1463
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addMiddleTarget(DividerSnapAlgorithm.java:369)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:324)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 2115
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:474)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.maybeAddTarget(DividerSnapAlgorithm.java:362)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addNonDismissingTargets(DividerSnapAlgorithm.java:325)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.addRatio16_9Targets(DividerSnapAlgorithm.java:353)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:305)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
07-15 16:51:55.254   745   745 I lsm666  : SnapTarget position = 2960
07-15 16:51:55.254   745   745 I lsm666  : java.lang.Exception
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm$SnapTarget.<init>(DividerSnapAlgorithm.java:478)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.calculateTargets(DividerSnapAlgorithm.java:317)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:138)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.policy.DividerSnapAlgorithm.<init>(DividerSnapAlgorithm.java:112)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.getSnapAlgorithm(SplitLayout.java:433)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.common.split.SplitLayout.<init>(SplitLayout.java:134)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.splitscreen.StageCoordinator.onTaskAppeared(StageCoordinator.java:956)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:438)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.wm.shell.ShellTaskOrganizer.onTaskAppeared(ShellTaskOrganizer.java:427)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1.lambda$onTaskAppeared$4$android-window-TaskOrganizer$1(TaskOrganizer.java:306)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.window.TaskOrganizer$1$$ExternalSyntheticLambda6.run(Unknown Source:6)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.os.Looper.loop(Looper.java:288)
07-15 16:51:55.254   745   745 I lsm666  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-15 16:51:55.254   745   745 I lsm666  : 	at java.lang.reflect.Method.invoke(Native Method)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-15 16:51:55.254   745   745 I lsm666  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

4. Split screen exit part

4.1 Return and exit

applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onStageHasChildrenChanged:1187, StageCoordinator (com.android.wm.shell.splitscreen)
-$$Nest$monStageHasChildrenChanged:-1, StageCoordinator (com.android.wm.shell.splitscreen)
onStatusChanged:1864, StageCoordinator$StageListenerImpl (com.android.wm.shell.splitscreen)
sendStatusChanged:377, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskVanished:276, StageTaskListener (com.android.wm.shell.splitscreen)
updateTaskListenerIfNeeded:552, ShellTaskOrganizer (com.android.wm.shell)
onTaskInfoChanged:465, ShellTaskOrganizer (com.android.wm.shell)
lambda$onTaskInfoChanged$6$android-window-TaskOrganizer$1:316, TaskOrganizer$1 (android.window)
run:-1, TaskOrganizer$1$$ExternalSyntheticLambda3 (android.window)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

4.2 Start full screen activity and exit


applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onStageVisibilityChanged:1079, StageCoordinator (com.android.wm.shell.splitscreen)
-$$Nest$monStageVisibilityChanged:-1, StageCoordinator (com.android.wm.shell.splitscreen)
onStatusChanged:1868, StageCoordinator$StageListenerImpl (com.android.wm.shell.splitscreen)
sendStatusChanged:377, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskInfoChanged:251, StageTaskListener (com.android.wm.shell.splitscreen)
onTaskInfoChanged:468, ShellTaskOrganizer (com.android.wm.shell)
lambda$onTaskInfoChanged$6$android-window-TaskOrganizer$1:316, TaskOrganizer$1 (android.window)
run:-1, TaskOrganizer$1$$ExternalSyntheticLambda3 (android.window)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

4.3 Drag and drop to exit normally

applyExitSplitScreen:735, StageCoordinator (com.android.wm.shell.splitscreen)
exitSplitScreen:730, StageCoordinator (com.android.wm.shell.splitscreen)
onSnappedToDismiss:1219, StageCoordinator (com.android.wm.shell.splitscreen)
lambda$snapToTarget$0:400, SplitLayout (com.android.wm.shell.common.split)
$r8$lambda$eePA67tW_LBGfBgW6IWST62hoPI:-1, SplitLayout (com.android.wm.shell.common.split)
run:-1, SplitLayout$$ExternalSyntheticLambda0 (com.android.wm.shell.common.split)
onAnimationEnd:458, SplitLayout$1 (com.android.wm.shell.common.split)
:-1, Animator$AnimatorListener (android.animation)
endAnimation:1333, ValueAnimator (android.animation)
doAnimationFrame:1575, ValueAnimator (android.animation)
doAnimationFrame:307, AnimationHandler (android.animation)
-$$Nest$mdoAnimationFrame:-1, AnimationHandler (android.animation)
doFrame:86, AnimationHandler$1 (android.animation)
run:1229, Choreographer$CallbackRecord (android.view)
run:1239, Choreographer$CallbackRecord (android.view)
doCallbacks:899, Choreographer (android.view)
doFrame:827, Choreographer (android.view)
run:1214, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7898, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:936, ZygoteInit (com.android.internal.os)

Guess you like

Origin blog.csdn.net/learnframework/article/details/131082401