安卓车机手机系统开发--多窗口模式之PIP详细讲解

视频教程讲解:
https://www.bilibili.com/video/BV1wj411o7A9/
在这里插入图片描述

1、PIP进入

官方解释及备注:
/** Always on-top (always visible). of other siblings in its parent container. */
public static final int WINDOWING_MODE_PINNED = 2;

app层:

  private void enterPiPMode() {
    
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
    
            if (mPictureInPictureParamsBuilder == null) {
    
    
                mPictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
            }
            if (videoView != null) {
    
    
                int mVideoWith = videoView.getWidth();
                int mVideoHeight = videoView.getHeight();
                if (mVideoWith != 0 && mVideoHeight != 0) {
    
    
                    //设置param宽高比,根据宽高比例调整初始参数
                    Rational aspectRatio = new Rational(mVideoWith, mVideoHeight);
                    mPictureInPictureParamsBuilder.setAspectRatio(aspectRatio);
                }

            }
            //进入pip模式
            enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
        }
    }

systemserver层面核心:
核心方法moveActivityToPinnedRootTask:


void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
            @Nullable ActivityRecord launchIntoPipHostActivity, String reason) {
    
    
      //省略
            // The intermediate windowing mode to be set on the ActivityRecord later.
            // This needs to happen before the re-parenting, otherwise we will always set the
            // ActivityRecord to be fullscreen.
            final int intermediateWindowingMode = rootTask.getWindowingMode();
        //省略
            //注意ActivityRecord设置的是intermediateWindowingMode即不是pip还是fullscreen
            r.setWindowingMode(intermediateWindowingMode);
            r.mWaitForEnteringPinnedMode = true;
            //省略
            //Task被尽快设置成了WINDOWING_MODE_PINNED
            rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
      //省略
      //这里会触发sendTaskAppeared
            rootTask.setDeferTaskAppear(false);

                  //省略
        } finally {
    
    
            mService.continueWindowLayout();
        }
			//进行了Task的windowmode设置后一般要触发ensureActivitiesVisible和resumeFocusedTasksTopActivities来保证系统所有Activity的显示正常
        ensureActivitiesVisible(null, 0, false /* preserveWindows */);
        resumeFocusedTasksTopActivities();

        notifyActivityPipModeChanged(r.getTask(), r);
    }

总结:
1、pip模式进入,systemserver层面主要有对ActivityRecord单独设置windowmode为fullscreen,对Task设置windowmode为pip模式
2、一般改变了Task相关的属性后都会触发ensureActivitiesVisible和resumeFocusedTasksTopActivities保证系统当前activity可以正常排列显示

2、 生命周期变化

launcher进入resume:


obtain:78, ResumeActivityItem (android.app.servertransaction)
resumeTopActivity:1434, TaskFragment (com.android.server.wm)
resumeTopActivityInnerLocked:5003, Task (com.android.server.wm)
resumeTopActivityUncheckedLocked:4938, Task (com.android.server.wm)
resumeTopActivityUncheckedLocked:4952, Task (com.android.server.wm)
resumeTopActivityUncheckedLocked:4984, Task (com.android.server.wm)
makeActiveIfNeeded:5765, ActivityRecord (com.android.server.wm)
makeVisibleIfNeeded:5697, ActivityRecord (com.android.server.wm)
setActivityVisibilityState:210, EnsureActivitiesVisibleHelper (com.android.server.wm)
process:143, EnsureActivitiesVisibleHelper (com.android.server.wm)
updateActivityVisibilities:1111, TaskFragment (com.android.server.wm)
lambda$ensureActivitiesVisible$18:4834, Task (com.android.server.wm)
accept:-1, Task$$ExternalSyntheticLambda23 (com.android.server.wm)
forAllLeafTasks:3160, Task (com.android.server.wm)
forAllLeafTasks:3148, Task (com.android.server.wm)
ensureActivitiesVisible:4833, Task (com.android.server.wm)
lambda$ensureActivitiesVisible$45:6217, DisplayContent (com.android.server.wm)
accept:-1, DisplayContent$$ExternalSyntheticLambda38 (com.android.server.wm)
forAllRootTasks:3172, Task (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2007, WindowContainer (com.android.server.wm)
ensureActivitiesVisible:6216, DisplayContent (com.android.server.wm)
ensureActivitiesVisible:1864, RootWindowContainer (com.android.server.wm)
ensureActivitiesVisible:1845, RootWindowContainer (com.android.server.wm)
setWindowingModeInSurfaceTransaction:4632, Task (com.android.server.wm)
lambda$setWindowingMode$16$com-android-server-wm-Task:4513, Task (com.android.server.wm)
run:-1, Task$$ExternalSyntheticLambda40 (com.android.server.wm)
inSurfaceTransaction:8282, WindowManagerService (com.android.server.wm)
setWindowingMode:4513, Task (com.android.server.wm)
setWindowingMode:4501, Task (com.android.server.wm)
moveActivityToPinnedRootTask:2114, RootWindowContainer (com.android.server.wm)
lambda$enterPictureInPictureMode$5$com-android-server-wm-ActivityTaskManagerService:3474, ActivityTaskManagerService (com.android.server.wm)
run:-1, ActivityTaskManagerService$$ExternalSyntheticLambda3 (com.android.server.wm)
enterPictureInPictureMode:3497, ActivityTaskManagerService (com.android.server.wm)
enterPictureInPictureMode:740, ActivityClientController (com.android.server.wm)
onTransact:878, IActivityClientController$Stub (android.app)
onTransact:124, ActivityClientController (com.android.server.wm)
execTransactInternal:1280, Binder (android.os)
execTransact:1244, Binder (android.os)

pip的app进入pasue
疑问1: 为啥pip只进行pause不进行stop

进入onPause

可以通过在服务端的PauseActivityItem构造时候打印对应的堆栈:

obtain:75, PauseActivityItem (android.app.servertransaction)
makeActiveIfNeeded:5779, ActivityRecord (com.android.server.wm)
setActivityVisibilityState:207, EnsureActivitiesVisibleHelper (com.android.server.wm)
process:143, EnsureActivitiesVisibleHelper (com.android.server.wm)
updateActivityVisibilities:1119, TaskFragment (com.android.server.wm)
lambda$ensureActivitiesVisible$18:4834, Task (com.android.server.wm)
accept:-1, Task$$ExternalSyntheticLambda23 (com.android.server.wm)
forAllLeafTasks:3160, Task (com.android.server.wm)
ensureActivitiesVisible:4833, Task (com.android.server.wm)
lambda$ensureActivitiesVisible$45:6216, DisplayContent (com.android.server.wm)
accept:-1, DisplayContent$$ExternalSyntheticLambda38 (com.android.server.wm)
forAllRootTasks:3172, Task (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2020, WindowContainer (com.android.server.wm)
forAllRootTasks:2013, WindowContainer (com.android.server.wm)
ensureActivitiesVisible:6215, DisplayContent (com.android.server.wm)
ensureActivitiesVisible:1864, RootWindowContainer (com.android.server.wm)
ensureActivitiesVisible:1845, RootWindowContainer (com.android.server.wm)
setWindowingModeInSurfaceTransaction:4632, Task (com.android.server.wm)
lambda$setWindowingMode$16$com-android-server-wm-Task:4513, Task (com.android.server.wm)
run:-1, Task$$ExternalSyntheticLambda40 (com.android.server.wm)
inSurfaceTransaction:8282, WindowManagerService (com.android.server.wm)
setWindowingMode:4513, Task (com.android.server.wm)
setWindowingMode:4501, Task (com.android.server.wm)
moveActivityToPinnedRootTask:2114, RootWindowContainer (com.android.server.wm)
lambda$enterPictureInPictureMode$5$com-android-server-wm-ActivityTaskManagerService:3474, ActivityTaskManagerService (com.android.server.wm)
run:-1, ActivityTaskManagerService$$ExternalSyntheticLambda3 (com.android.server.wm)
enterPictureInPictureMode:3497, ActivityTaskManagerService (com.android.server.wm)
enterPictureInPictureMode:740, ActivityClientController (com.android.server.wm)
onTransact:878, IActivityClientController$Stub (android.app)
onTransact:124, ActivityClientController (com.android.server.wm)
execTransactInternal:1280, Binder (android.os)
execTransact:1244, Binder (android.os)

堆栈中关键判断如下:

boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
    
    
        if (shouldResumeActivity(activeActivity)) {
    
    
         //省略
        } else if (shouldPauseActivity(activeActivity)) {
    
     //核心在与这里的shouldPauseActivity为true
            setState(PAUSING, "makeActiveIfNeeded");
            try {
    
    
                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
                        PauseActivityItem.obtain(finishing, false /* userLeaving */,
                                configChangeFlags, false /* dontReport */));
            } catch (Exception e) {
    
    
                Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
            }
        }
          @VisibleForTesting
    boolean shouldPauseActivity(ActivityRecord activeActivity) {
    
     //这里面的isFocusable是关键,即现在已经属于不可以焦点状态
        return shouldMakeActive(activeActivity) && !isFocusable() && !isState(PAUSING, PAUSED)&& (results == null);
    }
    
    @Override
    boolean isFocusable() {
    
    
        return super.isFocusable() && (canReceiveKeys() || isAlwaysFocusable());
    }
     boolean canReceiveKeys() {
    
    
        // TODO(156521483): Propagate the state down the hierarchy instead of checking the parent
        return getWindowConfiguration().canReceiveKeys()
                && (task == null || task.getWindowConfiguration().canReceiveKeys());
    }
       /**
     * Returns true if the windows associated with this window configuration can receive input keys.
     * @hide
     */
    public boolean canReceiveKeys() {
    
     //这里是WINDOWING_MODE_PINNED,所以返回false,这里就是核心关键地方导致focusable为false
        return mWindowingMode != WINDOWING_MODE_PINNED;
    }

总结精简后的流程图如下:
在这里插入图片描述

一般正常情况下Activity的Visible状态就会决定它是否要进入Stop

即Activity如果属于Pasued状态了系统如果触发了ensureActivitiesVisible的调用
则会遍历每一个Task的一个对应的EnsureActivitiesVisibleHelper的process方法:

void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
            boolean notifyClients) {
    
    
        reset(starting, configChanges, preserveWindows, notifyClients);
       //省略
        for (int i = mTaskFragment.mChildren.size() - 1; i >= 0; --i) {
    
    
            final WindowContainer child = mTaskFragment.mChildren.get(i);
            final TaskFragment childTaskFragment = child.asTaskFragment();
               //省略
            } else if (child.asActivityRecord() != null) {
    
    
                setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
            }
        }
    }

这里最先就是调用了reset

void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
            boolean notifyClients) {
    
    
        mStarting = starting;
        mTop = mTaskFragment.topRunningActivity();
        // If the top activity is not fullscreen, then we need to make sure any activities under it
        // are now visible.
        mAboveTop = mTop != null;
        mContainerShouldBeVisible = mTaskFragment.shouldBeVisible(mStarting);//这里的mContainerShouldBeVisible就代表Task是否可以显示,这个地方最为关键
        mBehindFullyOccludedContainer = !mContainerShouldBeVisible;
        mConfigChanges = configChanges;
        mPreserveWindows = preserveWindows;
        mNotifyClients = notifyClients;
    }

上面调用最为关键就是mTaskFragment.shouldBeVisible(mStarting)

  boolean shouldBeVisible(ActivityRecord starting) {
    
    
        return getVisibility(starting) != TASK_FRAGMENT_VISIBILITY_INVISIBLE;
    }

哈哈这里发现又是来比较getVisibility的值,这个地方我们前面有分析过的

因为小窗pip虽然进入了pasued状态,但是visible还是可以显示的true状态
知道task显示为true以后,再接下来看setActivityVisibilityState方法:

private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
            final boolean resumeTopActivity) {
    
    
     //省略
     //这里的mBehindFullyOccludedContainer再前面reset已经置为了false代表没有被覆盖
        r.updateVisibilityIgnoringKeyguard(mBehindFullyOccludedContainer);
        final boolean reallyVisible = r.shouldBeVisibleUnchecked();//这里会判断是否真正显示
        if (reallyVisible) {
    
    
            //可见状态,所以这里属于可见状态,导致不会进入makeInvisible
        } else {
    
    
        		//不可见调用makeInvisible
            r.makeInvisible();
        }

       //省略
    }
   //这里的 behindOccludedContainer为false,会返回visibleIgnoringKeyguard为true
     void updateVisibilityIgnoringKeyguard(boolean behindOccludedContainer) {
    
    
        visibleIgnoringKeyguard = (!behindOccludedContainer || mLaunchTaskBehind)
                && showToCurrentUser();
    }
       boolean shouldBeVisibleUnchecked() {
    
    
        final Task rootTask = getRootTask();
        //这里visibleIgnoringKeyguard所以不会进入,故shouldBeVisibleUnchecked一般返回true,代表可以显示
        if (rootTask == null || !visibleIgnoringKeyguard) {
    
     
            return false;
        }
        if (inPinnedWindowingMode() && rootTask.isForceHidden()) {
    
    
            return false;
        }

        if (hasOverlayOverUntrustedModeEmbedded()) {
    
    
            return false;
        }
        if (mDisplayContent.isSleeping()) {
    
    
            return canTurnScreenOn();
        } else {
    
    
            return mTaskSupervisor.getKeyguardController().checkKeyguardVisibility(this);
        }
    }

这里额外补充一点会进行stop情况是因为有调用makeInvisible方法:

void makeInvisible() {
    
    
       //省略
       try{
    
    
            final boolean deferHidingClient = canEnterPictureInPicture
                    && !isState(STARTED, STOPPING, STOPPED, PAUSED);
            setDeferHidingClient(deferHidingClient);
            setVisibility(false);

            switch (getState()) {
    
    
                case STOPPING:
                case STOPPED:
                    // Reset the flag indicating that an app can enter picture-in-picture once the
                    // activity is hidden
                    supportsEnterPipOnTaskSwitch = false;
                    break;
                case RESUMED:
                case INITIALIZING:
                case PAUSING:
                case PAUSED://已经处于PASUED状态了
                case STARTED:
                    addToStopping(true /* scheduleIdle */,
                            canEnterPictureInPicture /* idleDelayed */, "makeInvisible");//这里会加入到Stop列表
                    break;

                default:
                    break;
            }
        } catch (Exception e) {
    
    
            // Just skip on any failure; we'll make it visible when it next restarts.
            Slog.w(TAG, "Exception thrown making hidden: " + intent.getComponent(), e);
        }
    }

3、pip进入动画流程部分

pip进入动画流程是怎么样

system_server端触发:

05-24 00:18:00.318   568  1263 I test22  : onTaskInfoChanged taskInfo = TaskInfo{
    
    userId=0 taskId=1015 displayId=0 isRunning=true baseIntent=Intent {
    
     act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.myapplication11/.MainActivity } baseActivity=ComponentInfo{
    
    com.example.myapplication11/com.example.myapplication11.MainActivity} topActivity=ComponentInfo{
    
    com.example.myapplication11/com.example.myapplication11.MainActivity} origActivity=null realActivity=ComponentInfo{
    
    com.example.myapplication11/com.example.myapplication11.MainActivity} numActivities=1 lastActiveTime=466473 supportsSplitScreenMultiWindow=true supportsMultiWindow=true resizeMode=2 isResizeable=true minWidth=-1 minHeight=-1 defaultMinSize=220 token=WCT{
    
    RemoteToken{
    
    38f3882 Task{
    
    1a959c8 #1015 type=standard A=10118:com.example.myapplication11 U=0 visible=true visibleRequested=true mode=pinned translucent=false sz=1}}} topActivityType=1 pictureInPictureParams=PictureInPictureParams( aspectRatio=72/35 expandedAspectRatio=null sourceRectHint=null hasSetActions=false hasSetCloseAction=false isAutoPipEnabled=false isSeamlessResizeEnabled=true title=null subtitle=null isLaunchIntoPip=false) shouldDockBigOverlays=false launchIntoPipHostTaskId=0 displayCutoutSafeInsets=null topActivityInfo=ActivityInfo{
    
    dbedb93 com.example.myapplication11.MainActivity} launchCookies=[android.os.BinderProxy@7dc77d0] positionInParent=Point(0, 0) parentTaskId=-1 isFocused=false isVisible=true isSleeping=false topActivityInSizeCompat=false topActivityEligibleForLetterboxEducation= false locusId=null displayAreaFeatureId=1 cameraCompatControlState=hidden}
05-24 00:18:00.318   568  1263 I test22  : java.lang.Exception
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.TaskOrganizerController$TaskOrganizerCallbacks.onTaskInfoChanged(TaskOrganizerController.java:155)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.TaskOrganizerController.dispatchTaskInfoChanged(TaskOrganizerController.java:817)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.TaskOrganizerController.dispatchPendingEvents(TaskOrganizerController.java:728)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:837)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:784)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.WindowSurfacePlacer.continueLayout(WindowSurfacePlacer.java:97)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityTaskManagerService.continueWindowLayout(ActivityTaskManagerService.java:4388)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.RootWindowContainer.moveActivityToPinnedRootTask(RootWindowContainer.java:2138)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityTaskManagerService.lambda$enterPictureInPictureMode$5$com-android-server-wm-ActivityTaskManagerService(ActivityTaskManagerService.java:3474)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityTaskManagerService$$ExternalSyntheticLambda3.run(Unknown Source:6)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityTaskManagerService.enterPictureInPictureMode(ActivityTaskManagerService.java:3497)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityClientController.enterPictureInPictureMode(ActivityClientController.java:740)
05-24 00:18:00.318   568  1263 I test22  : 	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:878)
05-24 00:18:00.318   568  1263 I test22  : 	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:124)
05-24 00:18:00.318   568  1263 I test22  : 	at android.os.Binder.execTransactInternal(Binder.java:1280)
05-24 00:18:00.318   568  1263 I test22  : 	at android.os.Binder.execTransact(Binder.java:1244)

systemui端进行动画开始构造堆栈如下:

<init>:273, PipAnimationController$PipTransitionAnimator (com.android.wm.shell.pip)
<init>:-1, PipAnimationController$PipTransitionAnimator (com.android.wm.shell.pip)
<init>:558, PipAnimationController$PipTransitionAnimator$2 (com.android.wm.shell.pip)
ofBounds:557, PipAnimationController$PipTransitionAnimator (com.android.wm.shell.pip)
getAnimator:180, PipAnimationController (com.android.wm.shell.pip)
animateResizePip:1482, PipTaskOrganizer (com.android.wm.shell.pip)
scheduleAnimateResizePip:1171, PipTaskOrganizer (com.android.wm.shell.pip)
onTaskAppeared:630, PipTaskOrganizer (com.android.wm.shell.pip)
updateTaskListenerIfNeeded:555, 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:7897, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:937, ZygoteInit (com.android.internal.os)

动画的起始bounds和结束bounds确定:
在这里插入图片描述

疑问3: pip自己app大小变化靠啥确定及触发的

systemui进程进行动画结束以后,会进行对应的setBound的设置

 2049: 05-24 00:18:00.768   747   747 I test22  : java.lang.Exception
	行 2050: 05-24 00:18:00.768   747   747 I test22  : 	at android.app.WindowConfiguration.setBounds(WindowConfiguration.java:293)2051: 05-24 00:18:00.768   747   747 I test22  : 	at android.window.WindowContainerTransaction.setBounds(WindowContainerTransaction.java:92)2052: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.wm.shell.pip.PipTaskOrganizer.prepareFinishResizeTransaction(PipTaskOrganizer.java:1419)2053: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.wm.shell.pip.PipTaskOrganizer.finishResize(PipTaskOrganizer.java:1346)2054: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.wm.shell.pip.PipTaskOrganizer.-$$Nest$mfinishResize(Unknown Source:0)2055: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.wm.shell.pip.PipTaskOrganizer$1.onPipAnimationEnd(PipTaskOrganizer.java:181)2056: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.wm.shell.pip.PipAnimationController$PipTransitionAnimator.onAnimationEnd(PipAnimationController.java:307)2057: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:600)2058: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1333)2059: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1575)2060: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:307)2061: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)2062: 05-24 00:18:00.768   747   747 I test22  : 	at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)2063: 05-24 00:18:00.768   747   747 I test22  : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)2064: 05-24 00:18:00.768   747   747 I test22  : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)2065: 05-24 00:18:00.768   747   747 I test22  : 	at android.view.Choreographer.doCallbacks(Choreographer.java:899)2066: 05-24 00:18:00.768   747   747 I test22  : 	at android.view.Choreographer.doFrame(Choreographer.java:827)2067: 05-24 00:18:00.768   747   747 I test22  : 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)2068: 05-24 00:18:00.768   747   747 I test22  : 	at android.os.Handler.handleCallback(Handler.java:942)2069: 05-24 00:18:00.768   747   747 I test22  : 	at android.os.Handler.dispatchMessage(Handler.java:99)2070: 05-24 00:18:00.768   747   747 I test22  : 	at android.os.Looper.loopOnce(Looper.java:201)2071: 05-24 00:18:00.768   747   747 I test22  : 	at android.os.Looper.loop(Looper.java:288)2072: 05-24 00:18:00.768   747   747 I test22  : 	at android.app.ActivityThread.main(ActivityThread.java:7897)2073: 05-24 00:18:00.768   747   747 I test22  : 	at java.lang.reflect.Method.invoke(Native Method)2074: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)2075: 05-24 00:18:00.768   747   747 I test22  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:937)

然后systemserver进程会进行对应的setBounds

077: 05-24 00:18:00.768   568  1263 I test22  : java.lang.Exception
	行 2078: 05-24 00:18:00.768   568  1263 I test22  : 	at android.app.WindowConfiguration.setBounds(WindowConfiguration.java:293)2079: 05-24 00:18:00.768   568  1263 I test22  : 	at android.app.WindowConfiguration.setTo(WindowConfiguration.java:541)2080: 05-24 00:18:00.768   568  1263 I test22  : 	at android.content.res.Configuration.setTo(Configuration.java:1792)2081: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.applyChanges(WindowOrganizerController.java:534)2082: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.applyWindowContainerChange(WindowOrganizerController.java:1218)2083: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:428)2084: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:373)2085: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:179)2086: 05-24 00:18:00.768   568  1263 I test22  : 	at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:204)2087: 05-24 00:18:00.768   568  1263 I test22  : 	at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:163)2088: 05-24 00:18:00.768   568  1263 I test22  : 	at android.os.Binder.execTransactInternal(Binder.java:1285)2089: 05-24 00:18:00.768   568  1263 I test22  : 	at android.os.Binder.execTransact(Binder.java:1244)

小窗app端:

05-24 00:18:00.803  2031  2031 I test22  : mBounds Rect(606, 1958 - 1384, 2336) @ {
    
     mBounds=Rect(606, 1958 - 1384, 2336) mAppBounds=Rect(606, 1958 - 1384, 2336) mMaxBounds=Rect(0, 0 - 1440, 2960) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0}
05-24 00:18:00.803  2031  2031 I test22  : java.lang.Exception
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.WindowConfiguration.setBounds(WindowConfiguration.java:293)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.WindowConfiguration.setTo(WindowConfiguration.java:450)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.content.res.Configuration.setTo(Configuration.java:1047)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.content.res.ResourcesImpl.calcConfigChanges(ResourcesImpl.java:502)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.content.res.ResourcesImpl.updateConfiguration(ResourcesImpl.java:392)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.content.res.Resources.updateConfiguration(Resources.java:2142)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.content.res.Resources.updateSystemConfiguration(Resources.java:2155)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ResourcesManager.applyConfigurationToResources(ResourcesManager.java:1362)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ConfigurationController.handleConfigurationChanged(ConfigurationController.java:188)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ConfigurationController.handleConfigurationChanged(ConfigurationController.java:134)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ActivityThread.handleConfigurationChanged(ActivityThread.java:5996)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.servertransaction.ConfigurationChangeItem.execute(ConfigurationChangeItem.java:43)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.os.Handler.dispatchMessage(Handler.java:106)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.os.Looper.loopOnce(Looper.java:201)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.os.Looper.loop(Looper.java:288)
05-24 00:18:00.803  2031  2031 I test22  : 	at android.app.ActivityThread.main(ActivityThread.java:7897)
05-24 00:18:00.803  2031  2031 I test22  : 	at java.lang.reflect.Method.invoke(Native Method)
05-24 00:18:00.803  2031  2031 I test22  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
05-24 00:18:00.803  2031  2031 I test22  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:937)

ActivityRecord的WindowMode变化

发现在moveActivityToPinnedRootTask方法有如下注释:

     // Defer the windowing mode change until after the transition to prevent the activity
            // from doing work and changing the activity visuals while animating
            // TODO(task-org): Figure-out more structured way to do this long term.
            r.setWindowingMode(intermediateWindowingMode);

大概意思就是在进入pip动画过程种要禁止activity进行显示上面的变化,所以要设置为fullscreen的mode,等待动画完成才可以变化windowmode

ActivityRecord的windowmode相对特殊分为2个步骤:
1、进入pip时候,即进入pip的动画过程,是属于fullscreen的状态,但是task已经是pip了,所以需要ActivityRecord自己对应的override
2、当pip进入动画完成,则需要把ActivityRecord也设置成对应的windowmode为pip情况


--------- beginning of main

//ActivityRecord设置成对fullscreen,这样task的虽然已经是pip了但是ActivityRecord还是pip
06-29 16:12:14.011   567   737 I lsm11   : setWindowingMode windowingMode 1 ActivityRecord{
    
    4cde5aa u0 com.example.myapplication11/.MainActivity} t92}
06-29 16:12:14.011   567   737 I lsm11   : java.lang.Exception
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ConfigurationContainer.setWindowingMode(ConfigurationContainer.java:459)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.RootWindowContainer.moveActivityToPinnedRootTask(RootWindowContainer.java:2100)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ActivityTaskManagerService.lambda$enterPictureInPictureMode$5$com-android-server-wm-ActivityTaskManagerService(ActivityTaskManagerService.java:3474)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ActivityTaskManagerService$$ExternalSyntheticLambda3.run(Unknown Source:6)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ActivityTaskManagerService.enterPictureInPictureMode(ActivityTaskManagerService.java:3497)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ActivityClientController.enterPictureInPictureMode(ActivityClientController.java:740)
06-29 16:12:14.011   567   737 I lsm11   : 	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:878)
06-29 16:12:14.011   567   737 I lsm11   : 	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:124)
06-29 16:12:14.011   567   737 I lsm11   : 	at android.os.Binder.execTransactInternal(Binder.java:1280)
06-29 16:12:14.011   567   737 I lsm11   : 	at android.os.Binder.execTransact(Binder.java:1244)


//ActivityRecord设置成对undefined,这样就可以直接继承task的pip了


//systemui端
06-29 17:52:59.173   749   749 I lsm11   : java.lang.Exception
06-29 17:52:59.173   749   749 I lsm11   : 	at android.window.WindowContainerTransaction.setActivityWindowingMode(WindowContainerTransaction.java:206)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.wm.shell.pip.PipTaskOrganizer.prepareFinishResizeTransaction(PipTaskOrganizer.java:1407)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.wm.shell.pip.PipTaskOrganizer.finishResize(PipTaskOrganizer.java:1346)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.wm.shell.pip.PipTaskOrganizer.-$$Nest$mfinishResize(Unknown Source:0)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.wm.shell.pip.PipTaskOrganizer$1.onPipAnimationEnd(PipTaskOrganizer.java:181)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.wm.shell.pip.PipAnimationController$PipTransitionAnimator.onAnimationEnd(PipAnimationController.java:307)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:600)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1333)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1575)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:307)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.view.Choreographer.doCallbacks(Choreographer.java:899)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.view.Choreographer.doFrame(Choreographer.java:827)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.os.Handler.handleCallback(Handler.java:942)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.os.Handler.dispatchMessage(Handler.java:99)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.os.Looper.loopOnce(Looper.java:201)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.os.Looper.loop(Looper.java:288)
06-29 17:52:59.173   749   749 I lsm11   : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
06-29 17:52:59.173   749   749 I lsm11   : 	at java.lang.reflect.Method.invoke(Native Method)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
06-29 17:52:59.173   749   749 I lsm11   : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

//system_server端

06-29 16:12:14.636   567  1451 I lsm11   : setWindowingMode windowingMode 0 ActivityRecord{
    
    4cde5aa u0 com.example.myapplication11/.MainActivity} t92}
06-29 16:12:14.636   567  1451 I lsm11   : java.lang.Exception
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.ConfigurationContainer.setWindowingMode(ConfigurationContainer.java:459)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.Task$$ExternalSyntheticLambda30.accept(Unknown Source:8)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:281)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:204)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.internal.util.function.pooled.OmniFunction.accept(OmniFunction.java:92)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.ActivityRecord.forAllActivities(ActivityRecord.java:4515)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1657)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowContainer.forAllActivities(WindowContainer.java:1651)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.Task.setActivityWindowingMode(Task.java:4434)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.applyTaskChanges(WindowOrganizerController.java:599)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.applyWindowContainerChange(WindowOrganizerController.java:1222)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:427)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:372)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.applyTransaction(WindowOrganizerController.java:179)
06-29 16:12:14.636   567  1451 I lsm11   : 	at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:204)
06-29 16:12:14.636   567  1451 I lsm11   : 	at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:163)
06-29 16:12:14.636   567  1451 I lsm11   : 	at android.os.Binder.execTransactInternal(Binder.java:1285)
06-29 16:12:14.636   567  1451 I lsm11   : 	at android.os.Binder.execTransact(Binder.java:1244)

猜你喜欢

转载自blog.csdn.net/learnframework/article/details/130832582
今日推荐