ShellTransition源码分析:WMCore收集WindowContainer到finishNow执行

startTransition部分

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

  @Override
    public void startTransition(@NonNull IBinder transitionToken,
            @Nullable WindowContainerTransaction t) {
        startTransition(-1 /* unused type */, transitionToken, t);
    }
private IBinder startTransition(@WindowManager.TransitionType int type,
      @Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t) {
//省略            
		Transition transition = Transition.fromBinder(transitionToken);
		final WindowContainerTransaction wct =
		t != null ? t : new WindowContainerTransaction();
		//省略    
		if (t != null) {
				wctApplied = new Transition.ReadyCondition("start WCT applied");
				transition.mReadyTracker.add(wctApplied);
		} else {
				wctApplied = null;
		}

	 if (transition.shouldApplyOnDisplayThread()) {
		mService.mH.post(() -> {
		    synchronized (mService.mGlobalLock) {
		        transition.start();
		        applyTransaction(wct, -1 /* syncId */, transition, caller);
		        if (wctApplied != null) {
		            wctApplied.meet();
		        }
		    }
		});
		} else {
		  //调用transition.start方法启动
			transition.start();
			//再调用的applyTransaction方法
			applyTransaction(wct, -1 /* syncId */, transition, caller);
		}
//省略          
}

下面重点看看transition.start()和applyTransaction方法
frameworks/base/services/core/java/com/android/server/wm/Transition.java

    /**
     * Formally starts the transition. Participants can be collected before this is started,
     * but this won't consider itself ready until started -- even if all the participants have
     * drawn.
     */
    void start() {
        if (mState < STATE_COLLECTING) {
            throw new IllegalStateException("Can't start Transition which isn't collecting.");
        } else if (mState >= STATE_STARTED) {
            Slog.w(TAG, "Transition already started id=" + mSyncId + " state=" + mState);
            // The transition may be aborted (STATE_ABORT) or timed out (STATE_PLAYING by
            // SyncGroup#finishNow), so do not revert the state to STATE_STARTED.
            return;
        }
        mState = STATE_STARTED;//赋值mState为STATE_STARTED
        ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
                mSyncId);
        applyReady();//这里会判断当前是否ready,设置到SyncEngine中

        mLogger.mStartTimeNs = SystemClock.elapsedRealtimeNanos();

        mController.updateAnimatingState();
    }
    
  private void applyReady() {
        if (mState < STATE_STARTED) return;
        final boolean ready;
        if (mController.useFullReadyTracking()) {
            ready = mReadyTracker.isReady();
        } else {
            ready = mReadyTrackerOld.allReady();//获取是否ready值
        }
        boolean changed = mSyncEngine.setReady(mSyncId, ready);//再对sync进行设置ready
        if (changed && ready) {
            mLogger.mReadyTimeNs = SystemClock.elapsedRealtimeNanos();
            mOnTopTasksAtReady.clear();
            for (int i = 0; i < mTargetDisplays.size(); ++i) {
                addOnTopTasks(mTargetDisplays.get(i), mOnTopTasksAtReady);
            }
            mController.onTransitionPopulated(this);
        }
    }

start干的事情主要有2个:
1、把Transition的mState变成STATE_STARTED
2、调用applyReady方法,主要就是获取一下ready值,再设置,所以这个地方其实并没有说有完全设置read为true,而是根据当前ready值来

再接下来看看applyTransaction(wct, -1 /* syncId */, transition, caller);方法调用
因为wct其实是null传递过来的,但是applyTransaction实现主要又是针对wct有内容的情况,所以applyTransaction基本上啥也没干针对这种启动Activity场景。

那么到这里WMShell -----------------> WMCore这个过程就完成了,接下来的就是WMCore等待收集的WindowContainer完成绘制finish后,再触发onTransactionReady了.

WMCore收集的wc情况

前面Transition收集只讲解最基本的collect打开的ActivityRecord,但是打开一个Activity其实涉及的wc还是很多,比如打开Activity意味者上一Activity要被隐藏,而且隐藏的Activity还可能显示壁纸。
为了更好定位出collect收集了哪些wc,又是在什么时机收集的,这里加入日志打印更加方便定位
在这里插入图片描述
简单的桌面打开Activity场景一共有如下6次收集
在这里插入图片描述
收集的wc有3个是重复的,都是ActivityRecord,所以最后收集到了4个wc,即Transition的mParticipants集合一共有四个元素,一般对应的SyncGroup的mRootMembers也有四个元素。

第1次collect在startActivityUnchecked

 collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t-1}
 java.lang.Exception
 	at com.android.server.wm.Transition.collect(Transition.java:685)
 	at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1541)
 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
 	at android.os.Binder.execTransactInternal(Binder.java:1500)

第2次collect,因为Activity要启动肯定需要有对应Task,这里一般会新建一个Task,新建Task一般属于从无到有所以会触发collectExistenceChange进行收集Task并且置位mExistenceChange = true

   java.lang.Exception
   	at com.android.server.wm.Transition.collect(Transition.java:685)
   	at com.android.server.wm.Transition.collectExistenceChange(Transition.java:795)
   	at com.android.server.wm.TransitionController.collectExistenceChange(TransitionController.java:810)
   	at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2932)
   	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1829)
   	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1544)
   	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
   	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
   	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
   	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
   	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
   	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
   	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
   	at android.os.Binder.execTransactInternal(Binder.java:1500)
   	at android.os.Binder.execTransact(Binder.java:1444)

第3次collect因为要启动Activity在进行handleStartResult时候判断存在性有变化,所以会触发collectExistenceChange方法里面会collect,前面Activity已经收集过,所以这次也属于无效收集

    collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t266}
    java.lang.Exception
    	at com.android.server.wm.Transition.collect(Transition.java:685)
    	at com.android.server.wm.Transition.collectExistenceChange(Transition.java:795)
    	at com.android.server.wm.TransitionController.collectExistenceChange(TransitionController.java:810)
    	at com.android.server.wm.ActivityStarter.handleStartResult(ActivityStarter.java:1652)
    	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1551)
    	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1361)
    	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:782)
    	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1312)
    	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1257)
    	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1232)
    	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:910)
    	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5722)
    	at android.os.Binder.execTransactInternal(Binder.java:1500)
    	at android.os.Binder.execTransact(Binder.java:1444)

第4次collect,因为Launcher的ActivityPasue后,系统会保证前台Activity显示,所以触发收集,但是因为前面已经收集过了所以这次无效

    collect ActivityRecord{3762177 u0 com.android.dialer/.main.impl.MainActivity t266}
    java.lang.Exception
    	at com.android.server.wm.Transition.collect(Transition.java:685)
    	at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
    	at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
    	at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
    	at com.android.server.wm.EnsureActivitiesVisibleHelper.makeVisibleAndRestartIfNeeded(EnsureActivitiesVisibleHelper.java:238)
    	at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:181)
    	at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
    	at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
    	at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
    	at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
    	at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
    	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
    	at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
    	at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
    	at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
    	at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
    	at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
    	at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
    	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
    	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
    	at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
    	at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
    	at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
    	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
    	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
    	at android.os.Binder.execTransactInternal(Binder.java:1500)
    	at android.os.Binder.execTransact(Binder.java:1444)

第5次collect,因为Launcher要Pasue所以Launcher可见性就变得不可见,不可见设置时候就触发collect收集

    collect ActivityRecord{edc7080 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t253}
    java.lang.Exception
    	at com.android.server.wm.Transition.collect(Transition.java:685)
    	at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
    	at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
    	at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
    	at com.android.server.wm.ActivityRecord.makeInvisible(ActivityRecord.java:6330)
    	at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:208)
    	at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
    	at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
    	at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
    	at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
    	at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
    	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
    	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3142)
    	at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
    	at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
    	at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
    	at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
    	at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
    	at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
    	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
    	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
    	at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
    	at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
    	at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
    	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
    	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
    	at android.os.Binder.execTransactInternal(Binder.java:1500)
    	at android.os.Binder.execTransact(Binder.java:1444)

第6次collect的是ImageWallpaper,触发时机本质就是Launcher隐藏了,Launcher显示Wallpaper的,所以Launcher隐藏自然Wallpaper也要隐藏

12-17 11:18:13.227   544   562 I lsm888888: collect Window{7198a68 u0 com.android.systemui.wallpapers.ImageWallpaper}
12-17 11:18:13.227   544   562 I lsm888888: java.lang.Exception
    at com.android.server.wm.Transition.collect(Transition.java:685)
    at com.android.server.wm.WallpaperController.collectTopWallpapers(WallpaperController.java:771)
    at com.android.server.wm.Transition.collect(Transition.java:711)
    at com.android.server.wm.TransitionController.collect(TransitionController.java:804)
    at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5583)
    at com.android.server.wm.ActivityRecord.setVisibility(ActivityRecord.java:5544)
    at com.android.server.wm.ActivityRecord.makeInvisible(ActivityRecord.java:6330)
    at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:208)
    at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:130)
    at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1332)
    at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:5036)
    at com.android.server.wm.Task.$r8$lambda$DbhuUlekQ2cVQp1TiLmGb_W7C-g(Task.java:0)
    at com.android.server.wm.Task$$ExternalSyntheticLambda2.accept(R8$$SyntheticClass:0)
    at com.android.server.wm.Task.forAllLeafTasks(Task.java:3154)
    at com.android.server.wm.Task.forAllLeafTasks(Task.java:3142)
    at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:5035)
    at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:6549)
    at com.android.server.wm.DisplayContent.$r8$lambda$B9Mi2o96X6cYtjvyI8f4PcEeMbM(DisplayContent.java:0)
    at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda22.accept(R8$$SyntheticClass:0)
    at com.android.server.wm.Task.forAllRootTasks(Task.java:3166)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2213)
    at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2206)
    at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6548)
    at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1913)
    at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1896)
    at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1987)
    at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6599)
    at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:231)
    at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:698)
    at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
    at android.os.Binder.execTransactInternal(Binder.java:1500)
    at android.os.Binder.execTransact(Binder.java:1444)

进入SyncGroup等待期间

上面收集到了4个wc,那么Transition要可以进入下一个环节就必须要保证,4个wc都已经进行FinishSync才可以进入到Finished。
要进入Finished需要满足下面两个条件:

1、Transition处于ready = true状态,因为只有属于ready后,才会触发wc的是否finish检测
2、挨个遍历SyncGroup的mRootMember是否都进行finish,只要有一个没有就不可以

那么是什么时机设置ready为true呢?
堆栈可以看出来是在ActivityRecord.onStartingWindowDrawn会触发executeAppTransition调用到TransitionController.setReady

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

   void setReady(WindowContainer wc, boolean ready) {
        android.util.Log.i("lsm888888","call setReady "+ready,new Exception());
        if (!isCollecting() || mSyncId < 0) return;
        mReadyTrackerOld.setReadyFrom(wc, ready);
        applyReady();
    }
    
    private void applyReady() {
        if (mState < STATE_STARTED) return;
        final boolean ready;
        if (mController.useFullReadyTracking()) {
            ready = mReadyTracker.isReady();
        } else {
            ready = mReadyTrackerOld.allReady();
        }
        ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                "Set transition ready=%b %d", ready, mSyncId);
        boolean changed = mSyncEngine.setReady(mSyncId, ready);//根据当前mSyncId调用到SyncGroup的
    
    }

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

 boolean setReady(int id, boolean ready) {
        return getSyncGroup(id).setReady(ready);
    }
     /** returns true if readiness changed. */
        private boolean setReady(boolean ready) {
            if (mReady == ready) {
                return false;
            }
            ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready %b", mSyncId, ready);
            mReady = ready;//就是让mReady为true
            if (ready) {
                mWm.mWindowPlacerLocked.requestTraversal();
            }
            return true;
        }

相关堆栈

    call setReady true
    java.lang.Exception
    	at com.android.server.wm.Transition.setReady(Transition.java:943)
    	at com.android.server.wm.TransitionController.setReady(TransitionController.java:894)
    	at com.android.server.wm.TransitionController.setReady(TransitionController.java:899)
    	at com.android.server.wm.DisplayContent.executeAppTransition(DisplayContent.java:5690)
    	at com.android.server.wm.ActivityRecord.onStartingWindowDrawn(ActivityRecord.java:7012)
    	at com.android.server.wm.WindowState.performShowLocked(WindowState.java:4431)
    	at com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked(WindowStateAnimator.java:259)
    	at com.android.server.wm.DisplayContent.lambda$new$8(DisplayContent.java:1016)
    	at com.android.server.wm.DisplayContent.$r8$lambda$-dBz3LtsWovWVT0SE5m__EwNfT4(DisplayContent.java:0)
    	at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda32.accept(R8$$SyntheticClass:0)
    	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2833)
    	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2823)
    	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4663)
    	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4528)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1799)
    	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1816)
    	at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:5047)
    	at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:985)
    	at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:785)
    	at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:751)
    	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
    	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
    	at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
    	at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
    	at android.os.Handler.handleCallback(Handler.java:959)
    	at android.os.Handler.dispatchMessage(Handler.java:100)
    	at android.os.Looper.loopOnce(Looper.java:232)
    	at android.os.Looper.loop(Looper.java:317)
    	at android.os.HandlerThread.run(HandlerThread.java:85)
    	at com.android.server.ServiceThread.run(ServiceThread.java:46)

wc的Finished检测
检测触发函数是performSurfacePlacementNoTrace
在这里插入图片描述
具体检测逻辑代码


    void onSurfacePlacement() {
        if (mActiveSyncs.isEmpty()) return;

        while (!mTmpFinishQueue.isEmpty()) {
            if (visitBounds <= 0) {
                Slog.e(TAG, "Trying to finish more syncs than theoretically possible. This "
                        + "should never happen. Most likely a dependency cycle wasn't detected.");
            }
            --visitBounds;
            final SyncGroup group = mTmpFinishQueue.remove(0);
            final int grpIdx = mActiveSyncs.indexOf(group);
            // Skip if it's already finished:
            if (grpIdx < 0) continue;
            if (!group.tryFinish()) continue;//这里会调用到SyncGroup的
         
        }
    }

这里onSurfacePlacement主要就是调用SyncGroup的tryFinish方法

       /** @return `true` if it finished. */
        private boolean tryFinish() {
            if (!mReady) {//这里注意如果mReady为false就会直接返回
                Log.i("WindowManager"," tryFinish "+mReady);
                return false;
            }
            ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s",
                    mSyncId, mRootMembers);
            if (!mDependencies.isEmpty()) {
                ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d:  Unfinished dependencies: %s",
                        mSyncId, mDependencies);
                return false;
            }
            for (int i = mRootMembers.size() - 1; i >= 0; --i) {//遍历mRootMembers的每个wc
                final WindowContainer wc = mRootMembers.valueAt(i);
                if (!wc.isSyncFinished(this)) {//如果有一个没有完成就会中断
                    ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d:  Unfinished container: %s",
                            mSyncId, wc);
                    return false;
                }
            }
            finishNow();
            return true;
        }

重点看看wc.isSyncFinished方法,这里isSyncFinished重载比较多,重点判断还是WindowContainer为最重要

    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
        if (!isVisibleRequested()) {
            return true;
        }
        if (mSyncState == SYNC_STATE_NONE && getSyncGroup() != null) {
            prepareSync();
        }
        //如果WindowState还没绘制完成就是这个状态,其他非WindowState一般都不是这个SYNC_STATE_WAITING_FOR_DRAW
        if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW) {
            return false;
        }
        // READY
        // Loop from top-down.
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            final WindowContainer child = mChildren.get(i);
            //这里会遍历每个child是否isSyncFinished为true
            final boolean childFinished = group.isIgnoring(child) || child.isSyncFinished(group);
            if (childFinished && child.isVisibleRequested() && child.fillsParent()) {
                // Any lower children will be covered-up, so we can consider this finished.
                return true;
            }
            if (!childFinished) {
                return false;
            }
        }
        return true;
    }

上面可以看出其实遍历ActivityRecord的isSyncFinished其实就会遍历到它对应的WindowState的isSyncFinished。
所以核心看看WindowState相关的设置情况:
正常情况下只有WindowState会把mSyncState设置成SYNC_STATE_WAITING_FOR_DRAW
在这里插入图片描述
注意这里的prepareSync其实在前面的SyncGroup的addToSync时候调用的
在这里插入图片描述
在finishDraw时候才会设置的

在这里插入图片描述onSyncFinishedDrawing调用堆栈情况

onSyncFinishedDrawing:3929, WindowContainer (com.android.server.wm)
finishDrawing:5874, WindowState (com.android.server.wm)
finishDrawingWindow:2857, WindowManagerService (com.android.server.wm)
finishDrawing:350, Session (com.android.server.wm)
onTransact:815, IWindowSession$Stub (android.view)
onTransact:206, Session (com.android.server.wm)
execTransactInternal:1505, Binder (android.os)
execTransact:1444, Binder (android.os)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值