在具有外接螢幕 (透過 HDMI 或 DisplayPort) 的裝置上,顯示功能 (例如顯示模式和支援的 HDR 類型) 可能會動態變更,例如 Android TV 機上盒 (STB) 和 OTT 裝置。如果使用者從一個螢幕切換到另一個螢幕,或啟動裝置時未連接螢幕,就可能會出現 HDMI 熱插拔信號,導致發生這項變更。Android 12 以上版本包含架構變更,可處理熱插拔和動態螢幕功能。
本頁說明 Composer HAL 實作中,顯示器熱插拔和顯示器功能變更的處理方式。此外,本文也會討論如何管理相關聯的 Framebuffer,以及如何避免在這些情況下發生競爭狀況。
更新螢幕功能
本節說明 Android 架構如何處理 Composer HAL 啟動的螢幕功能變更。
OEM 必須實作 Composer HAL,使用 onHotplug(display, connection=CONNECTED)
通知架構顯示功能的所有變更,Android 才能正確處理顯示功能變更。實作完成後,Android 會依下列方式處理顯示功能變更:
- 偵測到螢幕功能有變時,架構會收到
onHotplug(display, connection=CONNECTED)
通知。 - 收到通知後,架構會捨棄顯示狀態,並使用
getActiveConfig
、getDisplayConfigs
、getDisplayAttribute
、getColorModes
、getHdrCapabilities
和getDisplayCapabilities
方法,透過 HAL 中的新功能重新建立顯示狀態。 - 架構重新建立新的顯示狀態後,會將
onDisplayChanged
回呼傳送至監聽這類事件的應用程式。
架構會在後續的 onHotplug(display, connection=CONNECTED)
事件中重新配置 Framebuffer。如要進一步瞭解如何正確管理 Framebuffer 記憶體,避免在配置新 Framebuffer 時發生失敗情形,請參閱「用戶端 Framebuffer 管理」。
處理常見的連線情境
本節說明在主要螢幕連線和中斷連線時,如何在實作項目中正確處理各種連線情況。
Android 架構是專為行動裝置打造,因此不支援中斷連線的主螢幕。如果主要螢幕實體中斷連線,HAL 必須在與架構互動時,以預留位置螢幕取代主要螢幕。
如果機上盒和電視 Dongle 連接的螢幕可中斷連線,可能會發生下列情況。如要導入這些情境的支援功能,請使用下表中的資訊:
情境 | 使用方式 |
---|---|
開機時未連接任何螢幕 |
|
主要螢幕已實際連接 |
|
主要螢幕已實際中斷連線 |
|
非 HDMI 連線注意事項
Android TV 僅支援下列解析度:
- 720x1280
- 1080x1920
- 2160x3840
- 4320x7680
機上盒或電視盒嘗試顯示不支援的解析度 (例如透過 CVBS 連線顯示 480i) 時,系統會向使用者顯示錯誤訊息。
如果機上盒或電視 Dongle 同時具備 HDMI 和非 HDMI 連接埠,則 HDMI 連接埠會做為主要螢幕,非 HDMI 連接埠則會停用。因此,如果非 HDMI 連線仍處於連線狀態,但 HDMI 連線中斷,系統就會將事件傳送至 SurfaceFlinger,且非 HDMI 螢幕的功能必須透過 getDisplayAttribute
和其他 iComposerClient
API (例如 getHdrCapabilities
) 反映。
使用連續設定 ID,避免競爭狀況
如果 Composer HAL 同時更新支援的螢幕設定,且架構呼叫 setActiveConfig
或 setActiveConfigWithConstraints
,可能會發生競爭情況。解決方法是實作 Composer HAL,使用連續 ID 並避免這個問題。
本節說明可能發生競爭情況的原因,以及如何實作 Composer HAL,使其使用序號 ID 來避免這類情況。
請考量下列事件順序,其中新顯示器設定「未獲指派新的連續 ID,導致競爭條件:
支援的多媒體廣告設定 ID 如下:
- id=1,1080x1920 60 Hz
- id=2,1080x1920 50 Hz
同時,Composer HAL 會處理螢幕設定的變更,並將內部狀態更新為一組新的螢幕設定,如下所示:
- id=1,2160x3840 60 Hz
- id=2,2160x3840 50 Hz
- id=3,1080x1920 60 Hz
- id=4,1080x1920 50 Hz
Composer HAL 會將
onHotplug
事件傳送至架構,通知支援的模式組合已變更。Composer HAL 會收到
setActiveConfig(display, config=1)
(來自步驟 2)。HAL 會將架構要求解讀為變更設定至 2160x3840 60 Hz,但實際上是需要 1080x1920 60 Hz。
使用非連續 ID 指派的程序在此結束,因為對所需設定變更的解讀有誤。
設定 Composer HAL 以使用連續 ID
為避免這類競爭狀況,原始設備製造商必須實作 Composer HAL,做法如下:
- Composer HAL 更新支援的螢幕設定時,會為新的螢幕設定指派新的連續 ID。
- 當架構使用無效的設定 ID 呼叫
setActiveConfig
或setActiveConfigWithConstraints
時,Composer HAL 會忽略該呼叫。
這些步驟可避免競爭狀況,如下方討論所示。
假設系統為新的螢幕設定指派新的連續 ID,請參考下列事件順序:
支援的多媒體廣告設定 ID 如下:
- id=1,1080x1920 60 Hz
- id=2,1080x1920 50 Hz
處理顯示設定變更時,系統會從下一個未使用的整數開始指派下一組設定 ID,如下所示:
id=3,2160x3840 60 Hz
id=4,2160x3840 50 Hz
id=5,1080x1920 60 Hz
id=6,1080x1920 50 Hz
Composer HAL 會將
onHotplug
事件傳送至架構,通知支援的模式組合已變更。Composer HAL 會收到
setActiveConfig(display, config=1)
(來自步驟 2)。由於 ID 已失效,Composer HAL 會忽略呼叫。
架構會接收並處理步驟 4 的
onHotplug
事件。並使用getDisplayConfigs
和getDisplayAttribute
函式呼叫 Composer HAL。架構會使用這些函式,找出所需解析度和刷新率 (1080x1920 和 60 Hz) 的新 ID (5)。架構會傳送另一個
setActiveConfig
事件,其中包含更新後的 ID 5。Composer HAL 會在步驟 5 中收到
setActiveConfig(display, config=5)
。HAL 會正確解讀架構要求,將設定變更為 1080x1920 60 Hz。
如上例所示,使用連續 ID 指派的程序可確保避免競爭狀況,並更新正確的螢幕設定變更。