WindowManagerService (WMS)
intro
在 Android 系統中,WindowManagerService (WMS) 是 Framework 最核心的服務之一,與 ActivityManagerService (AMS)、PackageManagerService (PMS) 並列為三大重量級系統服務。
它的主要職責可以歸納為:
- 視窗管理 (Window Management)
- 為應用 Activity、Dialog、System UI 提供視窗容器
- 與 SurfaceFlinger 協作進行畫面合成
- 輸入事件分發 (Input Dispatch)
- 協助 InputManagerService 將觸控/鍵盤事件分派到正確的視窗
- Z-Order 與堆疊管理
- 維護不同應用與視窗之間的前後順序
- 確保使用者看到的畫面符合邏輯
WMS 的複雜性,在於它不僅要處理 UI 呈現,還要與 系統安全、輸入控制、多視窗模式 緊密配合。可以說,若 AMS 是 Android 的「大腦」,那麼 WMS 就是 Android 的「眼睛與手」,決定了用戶看到什麼、能點擊什麼。
WMS 的架構與角色
- 運行位置
- WMS 運行在 system_server 進程,屬於系統服務。
- 它透過 Binder IPC 與應用 (App) 溝通,並與 SurfaceFlinger、IMS 等模組協作。
- 架構大概如下:
┌──────────────────────┐
│ Applications │
│ (Activity/Dialog/UI)│
└──────────┬───────────┘
│ Binder IPC
┌──────────▼───────────┐
│ WindowManagerService│
│ (system_server) │
├──────────┬───────────┤
│ 與 AMS協作│與 IMS 協作 │
└─────┬────┴─────┬─────┘
│ │
[SurfaceFlinger] [InputManagerService]
(畫面合成) (輸入分發)
視窗管理 (Window Management)
WMS 的最核心職責是為 Activity、Dialog、SystemUI 提供視窗容器,並控制其顯示與隱藏。
- Window 與 Surface
在 Android 中,每個視窗 (Window) 對應一個 Surface,Surface 是由 SurfaceFlinger 進行合成的圖層。
WMS 本身不負責畫面渲染,而是:
- 負責分配 Surface
- 管理 Window 屬性 (大小、位置、透明度)
- 將配置通知應用
- Window 分類
WMS 會將不同來源的 Window 分類,常見的有:
- 應用視窗 (Application Window):Activity、Dialog
- 子視窗 (Sub Window):如 PopupWindow、Menu
- 系統視窗 (System Window):狀態列、導航列、Toast、鍵盤
- 不同類型的視窗會被放置在不同層級的 Z-Order 中,決定顯示順序。
輸入事件分發 (Input Dispatch)
- IMS 與 WMS 的協作
- InputManagerService (IMS) 負責從硬體層 (如觸控屏、按鍵) 收集事件。
- WMS 負責告訴 IMS:哪個視窗在前台、哪個視窗擁有焦點。
- IMS 再將事件投遞給對應的 App 進程。
- 焦點管理
- 焦點 (Focus):只有獲得焦點的視窗,才能接收輸入事件。
- AMS 與 WMS 協作,決定哪個 Activity 在前台 → WMS 再將焦點設置給該視窗。
- 輸入事件分發流程
[觸控事件]
↓
[InputReader] (IMS 讀取事件)
↓
[InputDispatcher] (IMS 分發事件)
↓
[WMS 提供焦點資訊]
↓
[App 進程] → ViewRootImpl → DecorView → 對應的 View
Z-Order 與堆疊管理
- Z-Order 的定義
Z-Order 是視窗在螢幕上的前後順序。
例如:
- 前景:對話框、鍵盤、狀態列
- 背景:應用 Activity
- 視窗層級
Android 定義了多個 Window 層級,部分如下:
- APPLICATION_LAYER → 一般 Activity
- SYSTEM_ALERT_LAYER → 系統對話框 (如螢幕截圖提示)
- STATUS_BAR_LAYER → 狀態列
- NAVIGATION_BAR_LAYER → 導航列
WMS 在維護這些層級時,會確保 系統視窗 > 應用視窗,避免應用遮蓋系統 UI。
- 多任務與多視窗
- Android 7.0 以後引入 多視窗 (Multi-Window) 模式
- WMS 要同時管理多個 Activity 視窗的大小、位置、Z-Order
- Android 10 引入 多顯示器 (Multi-Display),使 WMS 能在不同螢幕上維護不同的視窗堆疊
WMS 的啟動與運作流程
- 啟動過程
- SystemServer 啟動 → 建立 WMS 實例
- WMS 初始化 → 註冊到 ServiceManager
- AMS 啟動 Activity → 請求 WMS 新增視窗
- WMS 分配 Surface → 通知 SurfaceFlinger
- App 透過 ViewRootImpl 與 WMS 溝通
- App 視窗建立流程
以 Activity.setContentView() 為例:
- ActivityThread 建立 ViewRootImpl
- ViewRootImpl 呼叫 WMS.addWindow()
- WMS 建立 WindowState,分配 Surface
- SurfaceFlinger 接管畫面合成
- WMS 更新 Z-Order,確保正確顯示
視窗建立流程大致如下:
[Activity] → setContentView()
↓
[ViewRootImpl] → addWindow()
↓
[WMS] 建立 WindowState
↓
[SurfaceFlinger] 分配與合成 Surface
↓
[畫面顯示在螢幕上]
WMS 與其他系統服務的協作
- AMS (ActivityManagerService)
- AMS 管理 Activity 邏輯
- WMS 負責 Activity 視窗的顯示
- SurfaceFlinger
- WMS 管理 Surface
- SurfaceFlinger 將各 Surface 合成到螢幕
- IMS (InputManagerService)
- WMS 告訴 IMS 哪個視窗擁有焦點
- IMS 再將事件分發到正確的 App
- PMS (PackageManagerService)
- WMS 可能需要查詢應用資訊,例如視窗權限 (如 SYSTEM_ALERT_WINDOW)
WMS 的挑戰與優化
- 性能挑戰
- 螢幕更新頻率 (60Hz → 120Hz)
- WMS 需要與 SurfaceFlinger 高效協作,減少掉幀
- 安全挑戰
- 防止惡意 App 使用 SYSTEM_ALERT_WINDOW 偽造 UI
- WMS 嚴格限制視窗層級與權限
- 多螢幕支援
- Android Q 後,WMS 支援外接顯示器
- 每個 Display 對應獨立的 Window Stack
summary
WindowManagerService (WMS) 是 Android Framework 中控制視覺與輸入的核心:
- 視窗管理:負責應用與系統視窗的建立、顯示與屬性管理
- 輸入事件分發:協助 IMS,將觸控/鍵盤事件派發到正確的視窗
- Z-Order 管理:維護視窗前後關係,確保 UI 行為正確
- 多視窗/多顯示支援:提升 Android 的多工體驗