Android11 以Window的视角来看FallbackHome的启动

在WMS中,使用WindowState代表着一个Window并维护着一个Window的"层级树",每个Window需要按照"层级"的规则进行排列。对于FallbackHome,其Window是挂载在home task上,而home task挂载在DefaultTaskDisplayArea这个叶子节点下,其父子关系如下:

1,home Task

home Task 在 SystemServer启动的时候,就会创建

c 复制代码
//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

c 复制代码
//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

c 复制代码
public void setWindowManager(WindowManagerService wm) {
        synchronized (mGlobalLock) {
            //省略
            mRootWindowContainer.setWindowManager(wm);
        }
    }

RootWindowContainer.setWindowManager

c 复制代码
//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

c 复制代码
//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

c 复制代码
//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方法,从这个方法开始分析

c 复制代码
//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

c 复制代码
//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的孩子。

c 复制代码
//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方法

c 复制代码
//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

c 复制代码
//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对象

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
@Override
    void addWindow(WindowState w) {
        super.addWindow(w);
		//删除
    }

调用其父类也就是WindowToken的addWindow方法

c 复制代码
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

相关推荐
AnalogElectronic3 小时前
问题记录,在使用android studio 构建项目时遇到的问题
android·ide·android studio
我爱松子鱼3 小时前
mysql之InnoDB Buffer Pool 深度解析与性能优化
android·mysql·性能优化
江上清风山间明月6 小时前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
子非衣10 小时前
MySQL修改JSON格式数据示例
android·mysql·json
openinstall全渠道统计13 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫13 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫13 小时前
一句话说透Android里面的查找服务
android
双鱼大猫13 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫13 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫14 小时前
一句话说透Android里面的Window的内部机制
android