在WMS中,使用WindowState代表着一个Window并维护着一个Window的"层级树",每个Window需要按照"层级"的规则进行排列。对于FallbackHome,其Window是挂载在home task上,而home task挂载在DefaultTaskDisplayArea这个叶子节点下,其父子关系如下:
1,home Task
home Task 在 SystemServer启动的时候,就会创建
//frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {//省略t.traceBegin("SetWindowManagerService");mActivityManagerService.setWindowManager(wm);t.traceEnd();//省略
}
AMS.setWindowManager
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setWindowManager(WindowManagerService wm) {synchronized (this) {mWindowManager = wm;mWmInternal = LocalServices.getService(WindowManagerInternal.class);mActivityTaskManager.setWindowManager(wm);}
}
ATMS.setWindowManager
public void setWindowManager(WindowManagerService wm) {synchronized (mGlobalLock) {//省略mRootWindowContainer.setWindowManager(wm);}}
RootWindowContainer.setWindowManager
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
void setWindowManager(WindowManagerService wm) {//省略final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);//省略}
先获取defaultTaskDisplayArea ,然后调用其getOrCreateRootHomeTask去创建home Task
//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
ActivityStack getOrCreateRootHomeTask(boolean onTop) {ActivityStack homeTask = getRootHomeTask();if (homeTask == null && mDisplayContent.supportsSystemDecorations()) {homeTask = createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME, onTop);}return homeTask;}
如果home Task没有创建过的话,就调用createStack去创建,传入的参数中,type为ACTIVITY_TYPE_HOME。在createStack方法中,继续调用createStackUnchecked
//frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
ActivityStack createStackUnchecked(int windowingMode, int activityType, int stackId,boolean onTop, ActivityInfo info, Intent intent, boolean createdByOrganizer) {final ActivityStack stack = new ActivityStack(mAtmService, stackId, activityType,info, intent, createdByOrganizer);//1if (launchRootTask != null) {//省略} else {addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);//2stack.setWindowingMode(windowingMode, true /* creating */);}return stack;}
注释1处,创建ActivityStack 对象,ActivityStack 继承自Task,注释2处将该ActivityStack设置为当前对象即defaultTaskDisplayArea的孩子。所以经过以上的调用流程,创建了一个home Task,其实home Task就是ActivityStack对象,然后挂载到DefaultTaskDisplayArea下。
2,FallbackHome Task
FallbackHome 是在 ActivityManagerService的 systemReady 中,调用startHomeOnAllDisplays 启动的,startHomeOnAllDisplays 会调用的ActivityStarter的executeRequest方法,从这个方法开始分析
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {//省略final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, callingFeatureId, intent, resolvedType, aInfo,mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,sourceRecord);//创建 ActivityRecord ,继承WindowToken//省略mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,restrictedBgActivity, intentGrants);
}
先创建一个ActivityRecord 对象,然后调用startActivityUnchecked继续处理。该方法最后调用setNewTask来创建Task
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private void setNewTask(Task taskToAffiliate) {final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;final Task task = mTargetStack.reuseOrCreateTask(mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);//1addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");//2//省略}
注释1处创建FallbackHome Task,mTargetStack为前面创建的home Task。注释2处,将前面创建的ActivityRecord设置为FallbackHome Task的孩子。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession,IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity,ActivityRecord source, ActivityOptions options) {Task task;if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {//省略} else {//省略task = new ActivityStack(mAtmService, taskId, info, intent, voiceSession,voiceInteractor, null /* taskDescription */, this);//新建task // add the task to stack first, mTaskPositioner might need the stack associationaddChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);//添加为home Task的孩子}//省略return task;}
可以看出,FallbackHome Task也是一个ActivityStack对象,FallbackHome Task的父亲为home Task
3,ActivityRecord
前面提到过,在executeRequest方法中创建ActivityRecord,最后调用到addOrReparentStartingActivity方法
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaprivate void addOrReparentStartingActivity(Task parent, String reason) {if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {parent.addChild(mStartActivity);//1} else {mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);}}
注释1处,parent为前面创建的FallbackHome Task,mStartActivity为前面创建的ActivityRecord,将ActivityRecord设置为FallbackHome Task的孩子
4,WindowState
在FallbackHome 的resume流程中,会调用ViewRootImpl的setView方法,最终调用到WMS的addWindow
//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(/*省略*/) {//省略final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid, userId,session.mCanAddInternalSystemWindow);//创建WindowState//省略win.mToken.addWindow(win);//省略
}
这里的win.mToken就是前面创建的ActivityRecord对象
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
@Overridevoid addWindow(WindowState w) {super.addWindow(w);//删除}
调用其父类也就是WindowToken的addWindow方法
void addWindow(final WindowState win) {//省略if (!mChildren.contains(win)) {addChild(win, mWindowComparator);mWmService.mWindowsChanged = true;}}
也是通过addChild将该WindowState设置为ActivityRecord的孩子
总结
本文以Window的视角来分析了一下FallbackHome的显示流程。我们知道了在WMS中,使用WindowState来代表一个窗口。WindowState的父亲是ActivityRecord,也就是说在WMS的层级树中,FallbackHome对应的WindowState挂载在ActivityRecord下。ActivityRecord挂载在FallbackHome Task(ActivityStack)下,FallbackHome Task又挂载在home Task(ActivityStack)下。而home Task的父亲是DefaultTaskDisplayArea