在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);//1
if (launchRootTask != null) {
//省略
} else {
addChild(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);//2
stack.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);//1
addOrReparentStartingActivity(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 association
addChild(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.java
private 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
@Override
void 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