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

相关推荐
雨白5 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空8 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭9 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日10 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安10 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑10 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟14 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体