系統裝飾

在 Android 9 (和以下版本) 中,SurfaceFlinger 和 DisplayManagerService 會假設最多有兩個實體螢幕,且硬式編碼 ID 為 0 和 1。如「靜態顯示裝置 ID」一文所述,SurfaceFlinger 現在會利用硬體合成器 (HWC) API 產生穩定的顯示裝置 ID,以便管理任意數量的實體顯示裝置。

在從 SurfaceControl#getPhysicalDisplayIdsDisplayEventReceiver 熱插拔事件取得 64 位元螢幕 ID 後,架構可以透過 SurfaceControl#getPhysicalDisplayToken 查詢實體螢幕的 IBinder 權杖。

在 Android 10 中,主內部螢幕為 TYPE_BUILT_IN,所有次要螢幕都會標記為 TYPE_HDMI,不論連線類型為何。因此,額外的內部螢幕目前會視為外部螢幕。解決方法是,如果已知 HWC 且可預測通訊埠分配邏輯,裝置專屬程式碼就能針對 DisplayAddress.Physical#getPort 做出假設。

實作

先前,螢幕會透過 32 位元 ID 識別,其中 0 代表內部螢幕、1 代表外部螢幕、[2, INT32_MAX] 代表 HWC 虛擬螢幕,而 -1 代表無效螢幕或非 HWC 虛擬螢幕。如要讓 SurfaceFlinger 和 DisplayManagerService 追蹤兩個以上的螢幕,並辨識先前看到的螢幕,請為螢幕提供穩定且持久的 ID。

如果 HWC 支援 IComposerClient.getDisplayIdentificationData 並提供顯示器 ID 資料,SurfaceFlinger 會剖析 EDID 結構,並為實體和 HWC 虛擬顯示器分配穩定的 64 位元顯示器 ID。系統會使用選項類型表示 ID,其中空值代表無效的顯示器或非 HWC 虛擬顯示器。在沒有 HWC 支援的情況下,SurfaceFlinger 會改用最多兩個實體螢幕的舊版行為。