WMS 如何在 system_server 中诞生
WMS 如何在 system_server 中诞生
WMS 不是由 Zygote 单独 fork 的进程,而是 system_server 中由 SystemServer 创建的服务对象。 它在启动时接入 ATMS、InputManagerService 和窗口策略,并与 ATMS 共享 WindowManagerGlobalLock,这些依赖决定了后续加窗和焦点更新的执行边界。
Binder 服务不等于独立进程
| 常见误解 | 正确理解 |
|---|---|
| WMS 是独立进程,和应用一样被 Zygote fork | WMS 运行在 system_server 进程内,由 SystemServer 直接创建 |
| WMS 自己有一把锁,ATMS 有另一把锁 | WMS 与 ATMS 共享同一个 WindowManagerGlobalLock |
WMS 不是由 Zygote 单独 fork 的进程,而是 SystemServer 在 system_server 内创建的服务对象。 它通过 Binder 暴露接口,但执行仍发生在宿主进程及其专用线程中。
启动主线
逐步解释:
- ① 前置依赖:SystemServer 先创建 ActivityTaskManager(ATMS)和 InputManagerService,WMS 构造时需要它们。
- ② 创建线程:
WindowManagerService.main()用DisplayThread.getHandler().runWithScissors()在 DisplayThread 上执行构造,保证线程归属确定。 - ③ 共享锁:构造函数里
installLock(this, INDEX_WINDOW)注册锁,并把mGlobalLock指向 ATMS 的全局锁,从此窗口和任务状态受同一把锁保护。 - ④ 初始化策略:
initPolicy()切到 UiThread,让 PhoneWindowManager 在正确的线程完成初始化。 - ⑤ 注册服务:
ServiceManager.addService(Context.WINDOW_SERVICE, wm)把 WMS 注册成系统服务,App 才能通过 Binder 拿到它。
依赖关系
| 依赖 | 提供什么 | WMS 用它做什么 |
|---|---|---|
| ActivityTaskManagerService | mGlobalLock、任务与 Activity 状态 | 窗口与任务共享状态、加窗时校验 ActivityRecord |
| InputManagerService | 输入系统入口 | 创建输入通道、下发输入窗口信息 |
| PhoneWindowManager | 窗口策略 | 校验加窗权限、计算布局约束 |
| DisplayManager 相关 | 显示信息 | 查找/创建 DisplayContent |
| SurfaceControl | 合成侧句柄 | 创建窗口 Layer、应用事务 |
全局锁与执行上下文
WMS 里大量方法用 synchronized (mGlobalLock) 包住。锁保护的是整个窗口状态树:mWindowMap、DisplayContent、WindowToken 和 WindowState 的读写。
执行上下文主要分四类:
| 上下文 | 运行位置 | 负责内容 |
|---|---|---|
| DisplayThread | system_server 专属线程 | WMS 构造、部分显示相关初始化 |
| UiThread | system_server 的 UI 线程 | Policy 初始化等 UI 工作 |
mH Handler | system_server 的线程 | 窗口消息(如超时、回调)调度 |
| Binder 线程 | system_server 线程池 | addWindow()、relayoutWindow() 等服务入口 |
一句话小结:WMS 是单进程、多线程、一把共享锁的系统服务。
源码证据
阅读目标:确认 WMS 由 SystemServer 在 DisplayThread 上创建,并与 ATMS 共享全局锁。
正文指针:SystemServer.java:1664;WindowManagerService.java:1116 / 1137 / 1165 / 1166 / 1409。
// SystemServer.java:1664
wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);// WindowManagerService.java:1137
DisplayThread.getHandler().runWithScissors(() ->
wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,
displayWindowSettingsProvider, transactionFactory,
surfaceControlFactory), 0);// WindowManagerService.java:1165
installLock(this, INDEX_WINDOW);
mGlobalLock = atm.getGlobalLock();这段代码证明: WMS 不是独立进程,而是 SystemServer 调用静态 main() 创建的 Java 对象;构造发生在 DisplayThread 上;mGlobalLock 直接来自 ATMS,两个服务共享同一把窗口锁。
调试边界
没有设备时以下结论保持“待设备验证”,命令只描述预期维度:
adb shell service list | grep window
adb shell dumpsys window预期:service list 出现 window 服务;dumpsys window 能展示显示器、窗口和焦点状态。若服务名缺失,先确认 system_server 是否还活着,不要直接判定 WMS 未启动。
源码入口
源码基准:android-14.0.0_r75。
以下文件默认位于 frameworks/base/,表中省略该前缀:
| 文件 | 关键位置 | 作用 |
|---|---|---|
services/java/com/android/server/SystemServer.java | 1664 行 WindowManagerService.main(...) | WMS 启动入口 |
| 同文件 | 1666 行 ServiceManager.addService(Context.WINDOW_SERVICE, wm) | 注册为系统服务 |
services/core/java/com/android/server/wm/WindowManagerService.java | 1116 行 public static WindowManagerService main() | 静态创建入口 |
| 同文件 | 1137 行 DisplayThread.getHandler().runWithScissors(...) | 构造线程归属 |
| 同文件 | 1165-1166 行 installLock / mGlobalLock = atm.getGlobalLock() | 共享全局锁 |
| 同文件 | 1216 行 mRoot = new RootWindowContainer(this) | 建立容器树根 |
| 同文件 | 1409 行 initPolicy() | 初始化窗口策略 |
services/core/java/com/android/server/wm/WindowManagerGlobalLock.java | 8 行 class WindowManagerGlobalLock | 全局锁类型 |