前言
简介
再看启动流程之前,我们先来了解一下WMS,他的全称是WindowManagerService。顾名思义,也就是窗口管理的服务类。有兴趣的小伙伴也可以看看之前的AMS启动流程以及zygote启动流程
职责
WMS 主要职责
- 窗口管理:负责启动、添加、删除窗口,管理窗口大小、层级,核心成员有:WindowContainer、RootWindowContainer、DisplayContent、TaskStack、Task、AppWindowToken、WindowState;
- 窗口动画:由其子系统 WindowAnimator 管理;
- 输入系统中转站:通过对窗口的触摸从而产生触摸事件,由 InputMethodService(IMS)对触摸事件进行处理,它会寻找一个最合适的窗口处理触摸反馈信息;
- Surface 管理:为每个窗口分配一块 Surface,用于绘制要显示的内容。
正文
SystemServer
frameworks/base/services/java/com/android/server/SystemServer
跟AMS一样,创建完zygote之后首先会创建SystemServer进程,为创建其他服务做准备,这里代码就不写注释了
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
......
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
SystemServiceRegistry.sEnableServiceNotFoundWtf = true;
createSystemContext();
}
......
try {
t.traceBegin("StartServices");
startBootstrapServices(t);
/// M: For mtk systemserver
sMtkSystemServerIns.startMtkBootstrapServices();
startCoreServices(t);
/// M: for mtk other service.
sMtkSystemServerIns.startMtkCoreServices();
startOtherServices(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
/// M: BOOTPROF
sMtkSystemServerIns.addBootEvent("Android:SysServerInit_END");
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在这里会启动系统核心服务(startCoreServices)、系统引导服务(startBootstrapServices)以及一些其他服务(startOtherServices),那么本文所探讨的WMS就在startOtherServices中。
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
t.traceBegin("startOtherServices");
final Context context = mSystemContext;
......
WindowManagerService wm = null;
......
//在初始化WMS之前,要先初始化sensor service(传感器服务)
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
//调用WMS的main方法
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
//添加至服务管理中
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
//并且AMS和IMS是通过WMS中转触发事件的,所以在这里把IMS也加上去
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();
//指定AMS中的WMS
t.traceBegin("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
t.traceEnd();
//初始化WMS完成
t.traceBegin("WindowManagerServiceOnInitReady");
wm.onInitReady();
t.traceEnd();
......
t.traceBegin("MakeWindowManagerServiceReady");
try {
//通知系统
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
t.traceEnd();
在其他类中设置WMS
ActivityManagerService
setWindowManager
public void setWindowManager(WindowManagerService wm) {
synchronized (this) {
//设置WMS
mWindowManager = wm;
//获取WMS本地系统服务接口,只能供系统内部使用
mWmInternal = LocalServices.getService(WindowManagerInternal.class);
//同时调用ATMS设置唯一的WMS
mActivityTaskManager.setWindowManager(wm);
}
}
ActivityTaskManagerService
setWindowManager
public void setWindowManager(WindowManagerService wm) {
synchronized (mGlobalLock) {
//初始化ATMS类中的WMS
mWindowManager = wm;
//注册根容器
mRootWindowContainer = wm.mRoot;
//注册系统默认值
mTempConfig.setToDefaults();
//初始化区域设置列表
mTempConfig.setLocales(LocaleList.getDefault());
mConfigurationSeq = mTempConfig.seq = 1;
//将系统默认的配置加入窗口根容器中,例如输入模式、屏幕尺寸和屏幕方向
mRootWindowContainer.onConfigurationChanged(mTempConfig);
//begin
//这三行代码是调用其他的控制管理器设置WMS
mLockTaskController.setWindowManager(wm);
mTaskSupervisor.setWindowManager(wm);
mRootWindowContainer.setWindowManager(wm);
//end
}
}
通过以上的代码我们可以发现,WMS并不是一次性通过某一个方法添加设置进其他需要它的类中,而是通过AMS->ATMS->其他类这样传递的方式依次加载。但是对比每个类的初始化时间,顺序却不一定是先有WMS,比如LockTaskController中的setWindowManager方法就明确写明了设置该类中使用的窗口管理器实例。这是必要的,因为在此类实例化期间窗口管理器不存在。那么也就说明LockTaskController的初始化时间在WMS之前。
WindowManagerService
main
main方法为我们创建并返回了一个WMS的实例,本方法就是将在方法外定义的一个私有静态WMS通过调用WMS的构造方法赋值。
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, DisplayWindowSettingsProvider
displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
Supplier<Surface> surfaceFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
atm, displayWindowSettingsProvider, transactionFactory, surfaceFactory,
surfaceControlFactory), 0);
return sInstance;
}
WindowManagerService
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, DisplayWindowSettingsProvider
displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
Supplier<Surface> surfaceFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
installLock(this, INDEX_WINDOW);
mGlobalLock = atm.getGlobalLock();
mAtmService = atm;
mContext = context;
//begin
//以下都是对一些资源初始化的判断
mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
mAllowBootMessages = showBootMsgs;
//为true则只启动核心服务
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
mHasPermanentDpad = context.getResources().getBoolean(
com.android.internal.R.bool.config_hasPermanentDpad);
mInTouchMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_defaultInTouchMode);
inputManager.setInTouchMode(mInTouchMode);
mDrawLockTimeoutMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_drawLockTimeoutMillis);
mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
mMaxUiWidth = context.getResources().getInteger(
com.android.internal.R.integer.config_maxUiWidth);
mDisableTransitionAnimation = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableTransitionAnimation);
mPerDisplayFocusEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_perDisplayFocusEnabled);
mAssistantOnTopOfDream = context.getResources().getBoolean(
com.android.internal.R.bool.config_assistantOnTopOfDream);
//end
//从资源中读取信箱配置控制运行时覆盖(就是例如模拟器在手机上运作结果画面不能完全填充,周边虚化的背景)
mLetterboxConfiguration = new LetterboxConfiguration(context);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mSurfaceControlFactory = surfaceControlFactory;
mTransactionFactory = transactionFactory;
mSurfaceFactory = surfaceFactory;
mTransaction = mTransactionFactory.get();
mPolicy = policy;
mAnimator = new WindowAnimator(this);
mRoot = new RootWindowContainer(this);
......
}
onInitReady
在这里面,最主要的时调用initPolicy这个方法,它会在当前线程池中取当前的线程设置管理类策略,然后添加进自己的watchdog中
public void onInitReady() {
initPolicy();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
createWatermark();
showEmulatorDisplayOverlayIfNeeded();
/// M: Add for App Resolution Tuner @{
if (mWmsExt.isAppResolutionTunerSupport()) {
mWmsExt.loadResolutionTunerAppList();
}
/// @}
}
systemReady
回调通知系统已经完成
public void systemReady() {
mSystemReady = true;
mPolicy.systemReady();
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
mTaskSnapshotController.systemReady();
mHasWideColorGamutSupport = queryWideColorGamutSupport();
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::loadSettings);
IVrManager vrManager = IVrManager.Stub.asInterface(
ServiceManager.getService(Context.VR_SERVICE));
if (vrManager != null) {
try {
final boolean vrModeEnabled = vrManager.getVrModeState();
synchronized (mGlobalLock) {
vrManager.registerListener(mVrStateCallbacks);
if (vrModeEnabled) {
mVrModeEnabled = vrModeEnabled;
mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
}
}
} catch (RemoteException e) {
// Ignore, we cannot do anything if we failed to register VR mode listener
}
}
}
getInputManagerCallback
t.traceBegin("StartInputManager");
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();
t.traceEnd();
InputManagerService会将回调设置在WMS中,设置好了之后然后去启动IMS
结尾
总结下来,SystemServer在初始化WMS时候主要做了这么几件事
- 初始化wms服务
- 将wms服务添加到systemserver中
- 初始化窗口管理策略类windowmanagerpolicy,调用onInitReady方法
- 通知wms 的显示准备完毕,调用displayReady
- 通知wms系统准备完毕,调用systemReady此时就可以读取屏幕的相关熟悉信息