RFC-0147:View 系統 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 說明 Fuchsia 平台的視窗系統,並確認其在平台中的角色。 |
問題 | |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-11-03 |
審查日期 (年-月-日) | 2022-01-05 |
摘要
這份 RFC 概略說明 Fuchsia 檢視器系統:一組 API,可用於推理及與視覺區域 (「檢視區域」) 及其生命週期互動。在其他平台上,這組功能也通常稱為視窗系統。這項 RFC 的範圍僅限於單螢幕產品。日後的 RFC 將說明如何變更以支援無頭裝置和/或多個螢幕。
View 是圖形內容的區域,也是 Fuchsia 上圖形和使用者互動的基礎單位。檢視畫面會連結起來,形成檢視區塊樹狀階層,並設有專屬的根檢視區塊。Fuchsia 的圖形合成器 Scenic 會從 View 樹狀結構中的每個 View 算繪圖形內容,產生顯示器的輸出內容。Scenic 和輸入管道負責將 UI 指定的使用者輸入內容 (例如鍵盤、滑鼠和觸控) 路由至正確的 View。
在 Fuchsia 平台支援「自備執行階段」的情況下,View 系統是其中的關鍵部分,也是產品開發人員使用多個執行階段的圖形內容,在 Fuchsia 上打造安全的視覺使用者體驗的機制。Fuchsia 的組合 API (Flatland 和 GFX) 是建構在 View 系統之上。
提振精神
這份 RFC 的目標是記錄並核准 View 系統的「狀態」。具體來說,我們想核准下列決策。
- 如要在 Fuchsia 上顯示圖形,元件必須使用 View 系統建立 View。唯一的例外狀況是單一視窗公用程式 UI,例如 Virtcon 和 Recovery UI,這些 UI 不會使用視窗功能,且在 Scenic 未執行時,設計用於資源受限的情況下執行。這些 UI 會直接與螢幕控制器互動。
- 檢視系統是元件整合 Fuchsia 平台支援的使用者觸控、滑鼠、鍵盤和無障礙服務的唯一方式。
- 檢視系統不關心所使用的合成策略 (GFX 與 Flatland),並為 Fuchsia 上的所有合成器實作提供共用基礎。
如要修改這些決策,您必須提出額外的 RFC 和/或更新此 RFC。
相關人員
協助人員:
hjfreyer@google.com
審查者:
這個部分預計在審查期間更新
- 圖像:reveman@google.com、jjosh@google.com、emircan@google.com
- 輸入:quiche@google.com
- 元件:ypomortsev@google.com
- 安全性:kostyak@google.com
- 一般:wez@google.com
諮詢:
sanjayc@google.com、hjfreyer@google.com、jjosh@google.com、lindkvist@google.com、geb@google.com
社會化:
草稿文件已傳送給 Scenic 和輸入團隊進行討論。
詞彙解釋
- Scenic
- Fuchsia 平台中的圖形合成元件
- View 系統 API 的唯一實作項目,包括與圖形組合 API 和 HCI API 的連結。
- 查看
- 圖像內容的視覺區域。
- 它具有座標系統、邊界框,以及透過 View 樹狀圖定義的祖系空間關係。
- 查看樹狀結構圖
- 系統上 View 的結構,以父子關係連結。檢視區塊樹狀結構的根檢視區塊通常會附加至螢幕。
- 螢幕
- 以像素為基礎的輸出裝置,也稱為螢幕。View 系統目前一次只支援一個連結至系統的螢幕。
- 螢幕會透過螢幕控制器管理。
- 顯示控制器
- 管理電腦連接螢幕的驅動程式。
- 僅與 Scenic 對話。
- 不適用於樹狀結構外部的用戶端。
- 場景管理工具
- 將根檢視畫面附加至螢幕的平台元件。
- 無障礙管理員
- 實作無障礙 API 的平台元件。
- 並具備 View 系統的特殊存取權。
- 系統殼層 (「Sys UI」、「System UI」)
- 開發人員 Shell ("tiles"、"present_view")
- 用於測試的系統殼層。通常這可讓開發人員獨立啟動 Fuchsia 元件。
- UI 用戶端
- 這是指涉檢視區塊擁有者的通用方式,並在本 RFC 中使用。
- 範例:Flutter 應用程式、具有多個頂層 View 的 Chromium。
設計
View 的定義
Fuchsia View 是 Fuchsia 上圖形和互動的基本單位。View 會定義視覺區域,用於向使用者顯示圖形內容。並非所有檢視畫面都會在特定時間顯示。每個 View 的圖形內容皆由 Fuchsia 元件提供。Scenic 會實作平台支援功能,用於管理檢視畫面並將其內容複合到螢幕上。
每個檢視畫面:
- 可納入其他 View (子項 View) 的內容,形成View 樹狀結構。
- 定義用於放置子內容的座標系統。
- 具有定界框,可定義該檢視畫面的可見部分 (以及選用的互動部分)。
- 可連結至 Scenic View 樹狀結構,也可以從中斷連結。(未連結的 View 可能存在,但不會將內容算繪至螢幕,也不會接收輸入內容。)
任何 Scenic 支援的圖形組合 API (例如 fuchsia.ui.composition 和 fuchsia.ui.scenic) 都必須提供方法,以建立 View 並管理其生命週期。日後推出的任何 Compose API 也必須在 View 系統上運作。Fuchsia 平台 HCI API (例如 指標和鍵盤) 會使用 View 來轉送輸入內容。(詳情請參閱下方的輸入說明)。
檢視樹狀結構
系統會建立一個全域 View Tree,由 Scenic 擁有及實作。View 樹狀結構有一個與螢幕連結的特殊根層級 View。Scenic 是唯一可直接操作所有 View 及其位置的 Fuchsia 元件。
檢視區塊樹狀結構中的每個檢視區塊都有其自身座標系統定義的邊界,以及以父項檢視區塊的座標系統表示的位置和方向。這些元素會共同決定圖形內容最終在螢幕上顯示的區域,以及回應使用者輸入內容的區域。
子檢視畫面
在座標系統中為 View 建立空白預留位置,View 就能嵌入其他 View 的額外圖形內容;預留位置稱為 viewport。這兩個 View 會在 View 樹狀結構中形成父項子項關係,其中父項 View 的 Viewport 會嵌入子項 View 的圖形內容。如要建立關係,父項和子項必須在建立 View 和 Viewport 時提供相符的符記。這些符記會以核心物件形式實作,因此無法複製。父項和子項可以透過多種方式取得這些比對符記,這些方式皆為 View 系統的外部。
從檢視區塊樹狀結構中連結或解除連結父項 View 時,也會連結/解除連結其子項 View。即使子樹已從全域 View Tree 中解除連結,子樹內的 View 之間連結仍會保留。
檢視畫面隔離
雖然 View 可以嵌入其他 View,但 View 系統不會將 View 的圖形內容存取權授予任何其他 View。這項隔離保證是 View 安全性的基礎之一。
將 Scenic 地圖檢視畫面顯示在螢幕上
Scenic 是唯一與顯示控制器通訊的元件。它會擷取整個 View 樹狀結構的圖形內容,以及樹狀結構中編碼的關係,建立單一圖片 (可能含有多個圖層)。然後程式會將硬體編程,以便顯示最終的畫面圖片。
查看擁有權
單一 FIDL 管道會將 View 中的內容提供給圖形組合 API,而該 API 則由 Scenic 實作。每個 FIDL 管道至 Scenic 的用戶端端點都稱為「UI 用戶端」,且 UI 用戶端最多只能建立一個 View。
檢視畫面可能來自各種元件,包括面向使用者的元件 (例如瀏覽器)、系統 UI,以及 Fuchsia 平台的元件 (例如 Accessibility Manager)。元件可能會建立多個管道,進而產生多個 View。因此,在某些情況下,單一元件可能會同時販售父項 View 和該 View 的子項 View。
為了將多個元件的圖形組合在一起,開發人員應在每個元件中建立 View 或多個 View,並使用子項 View 和 View 樹狀結構將這些 View 組合在一起。請注意,View Tree 階層不必與元件執行個體階層相符。在許多情況下,這些結構都會刻意呈現出截然不同的外觀。
Runtimes
如果元件是以較高階的語言 (例如 Dart 或 Javascript) 編寫,執行程式實作通常會負責建立及管理 View。使用這些語言的開發人員可能不瞭解基礎 OS 的許多細節;執行元件有責任將 View 生命週期轉譯為特定語言或特定執行階段的機制。
視窗管理與視窗系統與合成
Fuchsia 會將三個函式分開,這些函式有時會在其他平台上合併。
- 視窗管理功能整合了產品專屬政策,以及關於視窗行為的特定選項。在 Fuchsia 中,系統 UI 負責處理這項工作,且完全位於平台之外。
- 視窗系統是指低階視窗管理。在 Fuchsia 中,這項作業由 View 系統處理。
- 合成是指將來自多個來源的圖片合併,產生可供顯示的圖片。這項工作目前也是 Scenic 元件的責任,但日後可能會有所變更。
選擇將視窗系統和合成作業分開,可為圖形呈現提供快速路徑,並可實現高效的實作方式。雖然目前的 View System 和合成器主要都是在 Scenic 中實作,但 API 和程式碼卻是分開的。透過這種分離方式,View 系統就能支援多種合成策略 (Flatland 和 GFX)。
將視窗管理納入產品層級考量,可將政策邏輯保留在平台之外,確保平台和產品之間的明確區隔。
輸入
檢視畫面系統是 Fuchsia 平台用來決定如何路由使用者輸入內容 (例如指標事件或鍵盤事件) 的主要機制。Fuchsia 的使用者輸入 API 設計方式,可讓每個管道都限定為特定檢視畫面。系統會根據目前的 View 焦點 (鍵盤事件) 和/或與輸入事件位置相對應的 View (觸控或滑鼠事件),將輸入內容路由至 View。資料檢視只能在連線至 View Tree 時接收使用者輸入內容。
多個 View 可能會參與同一個事件的輸入處理作業。特定產品的視窗管理員可能會根據產品政策設定這項轉送作業,例如授予系統 UI 全域存取權,以便存取滑鼠事件。詳情請參閱「使用者輸入架構」。這套系統可讓多個執行階段的 View 提供流暢的使用者體驗,包括解析觸控手勢的功能。
這項做法的一個重要意涵是,Fuchsia 平台以外的元件無法直接存取來自驅動程式庫輸入事件。必須透過 View 系統接收這項資訊。
查看「專注模式」
在任何時間點,View Tree 都會有一個特殊的 View,稱為「focused」View。焦點 View 通常是使用者預期會收到使用者輸入內容的 View。Fuchsia 的輸入子系統會使用 View 焦點,判斷要將輸入內容導向何處。如需更多資訊,請參閱 Focus Chain 說明文件。父項 View 擁有者可以在子樹狀結構中控制 View 焦點。
ViewRef
平台會使用稱為 ViewRefs 的符記來識別及傳達 View 相關資訊。ViewRef 是特定 View 的專屬參照,在系統重新啟動前,該參照都會保持不變。它是以核心物件形式實作,其句柄可自由複製,並透過任意通訊協定傳送至其他元件。
View 系統 API 大量使用 ViewRef,為每個 View 提供穩定的跨元件參照。ViewRef 也可用於傳送關於相關 View 的生命週期事件。這可讓平台內部和外部的其他元件,針對 View 和其生命週期進行通訊,並將使用者輸入內容和無障礙通訊協定轉送至 View。
實作
Scenic 是 View 系統的權限來源,因為 View 樹狀結構和核心 View 管理 API 是在 Scenic 中實作。每個用戶端都會使用其 ViewRef 註冊,以便接收關聯 View 的使用者輸入和無障礙事件。Scenic 目前支援兩個圖形合成 API:fuchsia.ui.scenic (舊版) 和 fuchsia.ui.composition (開發中)。View 系統與各項服務獨立運作,但彼此緊密結合。
API 實作詳細資料不在本 RFC 的討論範圍,但您可以參閱下方的相關 API。值得一提的是,這些 API 是在多年的過程中逐漸演進。日後可能會簡化部分內容。
檢視系統中涉及的平台元件
- 風景
- 輸入管道
- Scene Manager (或舊版系統的 Root Presenter)
- Accessibility Manager
- 文字管理工具
用於管理 View 的 API
- fuchsia.ui.views
- 查看參照、查看符記定義
- 查看聚焦管理
- fuchsia.ui.composition
- 建立 View、移動 View、調整 View 大小、連結/中斷 View
- fuchsia.ui.policy
- 將系統 UI 檢視畫面連結至根檢視畫面
- fuchsia.ui.app.ViewProvider
- 透過元件建立 SurfaceView
- fuchsia.web.Frame
- 建立網頁用戶端檢視畫面
用於使用者輸入的 API
- fuchsia.ui.pointer
- 指標事件
- fuchsia.ui.input3
- 鍵盤輸入
- fuchsia.ui.shortcut
- 鍵盤快速鍵
無障礙 API
- fuchsia.accessibility.semantics
- 允許 View 傳送無障礙功能的語意資訊
- fuchsia.ui.annotation
- 允許無障礙功能服務醒目顯示目前聚焦的 UI 元件
成效
View 系統的許多層面都會影響圖形和輸入效能。我們會在下方說明一些重要事項。
- 所有執行階段皆相同:Fuchsia 的自帶執行階段原則表示 Fuchsia 上的所有執行階段都使用相同的事件轉送作業,且沒有任何執行階段獲得優先處理。
- 一次轉譯:Scenic 可讓您結合不同 View 的圖形內容,且不必重新轉譯,因為它知道 View 位置,並可正確將圖形內容轉送至顯示器驅動程式庫。
- 高效率調度:Scenic 會公開焦點資訊,讓非圖形使用者輸入內容 (例如鍵盤事件) 可直接從處理該輸入內容的元件調度。
安全性和隱私權考量
檢視系統會提供多項保證,確保在 Fuchsia 上安全地組合圖形內容,這些保證可奠定安全使用者體驗的基礎。不過,View 系統本身無法保證每個使用者體驗都安全無虞,只能保證 View 系統遵守自身的安全保證。
View 系統會透過以下方式,嘗試啟用安全的使用者體驗:
- 將擁有及操作 View Tree 的單一責任委派給 Scenic。
- 將在螢幕上顯示圖形內容的唯一責任,委派給 Scenic。
- 禁止 UI 用戶端在沒有相符的 Viewport 或 ViewRef 的情況下操控其他 View。
- 禁止 UI 用戶端使用 View 系統檢查其他 UI 用戶端 View 的內容。
- 只允許 UI 用戶端將輸入內容插入其 View 子區塊。
- 只有在連線至檢視區塊樹狀結構時,才允許 View 取得焦點並接收輸入內容。
UI 安全性仰賴元件架構針對能力轉送提供的保證。我們會在日後的 RFC 中說明 View 安全性相關細節。
測試
檢視系統是在多層抽象層級實作,因此會採用分層方式進行測試。
在 fuchsia.git 中:
- Scenic 元件程式碼庫中的 View Tree 和 View 生命週期單元測試。
- 位於 /src/ui/tests 中的 UI 整合測試,可執行 View 系統 API 相關的契約。
- 這些 API 會由 Scenic、Scene Manager、Input Pipeline、Accessibility Manager 和 Text Manager 等平台元件販售及使用。
- fuchsia.ui.observation.test API 會用於樹狀結構內的整合測試,用於檢查 View 系統行為。
樹狀結構外:
- 執行階段 (例如 Chromium 和 Flutter) 會編寫整合測試,以便執行 View System API
- 產品會編寫端對端測試,間接測試 View 系統。
說明文件
這份 RFC 概略說明 View 系統的角色和職責。我們會撰寫文件和可能的額外 RFC,以便說明詳細資訊。
部分 Scenic 說明文件也需要根據此 RFC 和 Flatland 即將實施的變更進行更新。
缺點、替代方案和未知事項
已知限制
View 系統目前缺乏在多個 View 之間同步更新的機制。
View 系統負責將功能路由至公開 View (使用 ViewRef) 的執行階段。這與透過 Fuchsia 元件架構進行的能力轉送概念上有重疊之處,但目前是完全分開的。日後,在元件架構中支援 View 功能可能會更有利。
目前的 API 只允許 View 擁有者建立子 View。對於希望建立多個頂層視窗的應用程式而言,這並非理想做法。
由於 View 系統 API 是經過多年的自然演進,並由許多不同的貢獻者共同開發,因此目前對執行階段開發人員的認知負擔相當高。日後我們會提供更完善的說明文件和範例,並盡可能簡化 API,以減少這種情況。
替代方案
View 系統架構提供多種架構選項。
- 所有含有圖片的產品都必須使用 View 系統。
- 或者,您可以選擇使用 Scenic,產品也可以包含自己的合成器。這需要將許多低階 API 公開到樹狀結構之外。
- 目前做法的優點:
- 跨執行階段的行為一致性 (包括無障礙和輸入)
- 一致的安全保證
- Display API 可在不破壞用戶端的情況下進行改良
- 目前做法的缺點:
- 產品自訂項目較少
- 執行階段整合的複雜度
- 如果有產品需要在 Fuchsia 上建構,這個版本可能會在日後變更。
- View 系統會分散至多個元件,包括 Scenic 和輸入管道。
- 或者,我們也可以將整個 View 系統建構到 Scenic 中。
- 目前做法的優點:
- 關注點分離:圖形組合、視窗管理和產品政策皆分開處理。
- 透過委派合成功能,允許高效能圖形路徑
- 與 UI 相關的元件可獨立發展
- 即使子系統 (例如文字輸入) 當機,也能讓圖形持續運作
- 目前做法的缺點:
- 多個程序可能會透過 IPC 增加延遲
- 增加元件之間的協調/同步處理複雜度
既有技術與參考資料
- View 系統和 Scenic 與 X Windows 系統共用部分架構。
- 其他方面則與 Wayland 通訊協定有更多共同之處。
- 輸入架構 RFC 詳細說明 View 系統如何與 Fuchsia 的使用者輸入子系統互動。