WindowManager 擴充功能

Jetpack WindowManager 程式庫可讓應用程式開發人員支援新的裝置板型規格和多視窗環境。

WindowManager 擴充功能 (擴充功能) 是選擇性的 Android 平台模組,可啟用各種 Jetpack WindowManager 功能。這個模組會透過 frameworks/base/libs/WindowManager/Jetpack 中的 Android 開放原始碼計畫實作,並運送至支援 WindowManager 功能的裝置上。

擴充功能模組分發

如果裝置 makefile 中已啟用擴充功能,系統會將擴充功能編譯為 .jar 程式庫,並放置在裝置的 system_ext 分區。

如要在裝置上啟用擴充功能,請在產品裝置 makefile 中加入以下內容:

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

這會在裝置上啟用 androidx.window.extensionsandroidx.window.sidecar 套件,並設定 persist.wm.extensions.enabled 屬性。在 makefile 中加入這些套件也會在 etc/permissions/ 中放置宣告,讓應用程式程序可以使用這些宣告。當 Jetpack WindowManager 程式庫使用時,模組通常會在應用程式程序中載入並執行,因此模組作業與用戶端架構程式碼類似,如下圖所示:

圖 1. 類似於平台程式碼,WindowManager 擴充功能會載入至應用程式程序。

androidx.window.extensions 模組是目前開發中的擴充功能模組。androidx.window.sidecar 模組是舊版模組,內含與早期 Jetpack WindowManager 版本相容,但不再主動維護。

下圖顯示判斷 androidx.window.extensionsandroidx.window.sidecar 使用方式的邏輯。

圖 2. 存取 androidx.window.extensionsandroidx.window.sidecar 的決策樹。

擴充功能模組

擴充功能可為摺疊式大螢幕裝置和支援在外接螢幕上執行視窗功能的裝置提供視窗功能。這些功能領域包括:

除非裝置硬體不支援對應的功能,否則擴充功能的原始設備製造商 (OEM) 實作項目可以提供空值的元件或元件,其中含有 WindowExtensions 介面中方法的預設或虛設常式實作,除非相容性定義說明文件 (CDD) 7.1.1.1 中明確要求該項功能。

Extensions 和 Jetpack API

除了公開平台 API 之外,WindowManager Extensions 模組也提供專屬的 API 介面。擴充功能模組是在非開發人員的 androidx.window.extensions Jetpack 程式庫中公開開發,因此 Jetpack WindowManager (androidx.window) 可在編譯期間連結至模組。Extensions API 介面通常會提供較低層級的 API。

擴充功能提供的 API 僅供 Jetpack WindowManager 程式庫使用。應用程式開發人員不會直接呼叫 Extensions API,為確保功能正確,您不得在 Gradle 建構檔案中將擴充功能程式庫新增為應用程式的依附元件。請勿直接將 Extensions 程式庫預先編譯到應用程式中,而是請依賴執行階段載入作業,以免載入預先編譯和執行階段提供的 Extensions 類別混合情況。

Jetpack WindowManager (androidx.window) 應新增為應用程式依附元件,並提供面向開發人員的公開 API,包括 WindowManager 擴充功能功能的 API。WindowManager 程式庫會自動將 Extensions 載入應用程式程序,並將較低層級的 Extensions API 包裝為較高層級的抽象項目和更專注的介面。WindowManager Jetpack API 遵循現代 Android 應用程式開發的標準,旨在整合使用其他 AndroidX 程式庫的程式碼集,提供便利的互通性。

擴充功能版本和更新

擴充功能模組可與 Android 平台每年或每季更新一併更新。季度更新可讓 Extensions API 級別在 Android 平台 API 更新之間提升,加快迭代作業,並讓原始設備製造商有時間在硬體推出前,為新功能新增官方 API 存取權。

下表列出各種 Android 版本的 androidx.window.extensions API 版本。

Android 平台版本 WindowManager Extensions API 級別 androidx.window.extensions API 版本
Android 15 6 1.5.0 (即將推出)
Android 14 QPR3 5 1.4.0 (即將推出)
Android 14 QPR1 4 1.3.0
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

每當現有的穩定 API 介面 (右欄) 有所新增時,Extension API 級別 (中間資料欄) 就會增加。

回溯相容性和前瞻相容性

Jetpack WindowManager 可處理頻繁的 API 級別更新、快速的 API 演進,以及回溯相容性等複雜問題。在應用程式程序中執行程式庫程式碼時,程式庫會檢查宣告的 Extensions API 級別,並根據宣告的層級提供功能的存取權。

為了避免應用程式在執行階段異常終止,WindowManager 也會根據宣告的 Extensions API 級別,對可用的 Extensions API 執行執行階段 Java 反射檢查。如果不相符,WindowManager 可以停用 (部分或完全) 使用擴充功能,並回報相關功能無法供應用程式使用。

WindowManager 擴充功能會以 system_ext 模組的形式實作,該模組會使用私人平台 API 呼叫 WindowManager 核心、DeviceStateManager 和其他系統服務,以實作擴充功能。

在對應的季度或年度 Android 平台版本之前 (版本已定案),而擴充功能的預先發布版可能無法維持相容性。您可以在版本分支版本 window:extensions:extensions API 文字檔案中找到 Extensions API 的完整記錄。

新版 Extensions 必須繼續與編譯至應用程式的舊版 WindowManager 搭配運作,以維持向前相容性。為確保這項功能,Extensions API 的任何新版本都只會新增新的 API,不會移除舊版 API。因此,採用舊版 WindowManager 的應用程式可以繼續使用應用程式編譯時所用的舊版 Extensions API。

CTS 驗證可確保裝置上任何已宣告的 Extensions API 版本,都包含該版本和先前版本的所有 API,且這些 API 都能正常運作。

成效

根據預設,自 Android 14 (API 級別 34) 開始,擴充功能模組會在非 Bootclasspath 系統類別載入器中快取,因此不會因為在應用程式啟動時將模組載入記憶體而受到影響。在用戶端和伺服器之間執行其他處理序間通訊 (IPC) 呼叫時,使用個別模組功能可能會稍微影響應用程式的效能特性。

模組

活動嵌入

活動嵌入元件提供一組功能,可讓應用程式在父項應用程式的範圍內,整理活動視窗呈現方式。這包括在多窗格版面配置中並排顯示兩個活動,方便為舊版應用程式進行大螢幕最佳化。

所有內建顯示大小等於或大於 sw600 dp 的裝置,都必須提供活動嵌入元件。在支援外接螢幕連線的裝置上,也必須啟用活動嵌入功能,因為在執行階段連線外接螢幕時,應用程式可能會以較大的尺寸顯示。

裝置設定

只需按照「擴充功能模組發布」一節的說明啟用擴充功能模組,就不需要進行特定的裝置設定。建議您在所有支援多視窗模式的裝置上啟用擴充功能。日後的 Android 版本可能會使一般手持裝置和大螢幕裝置設定需要使用擴充功能。

視窗版面配置資訊

當折疊式裝置的轉軸跨越應用程式視窗時,視窗版面配置資訊元件會識別轉軸的位置和狀態。視窗版面配置資訊可讓應用程式在摺疊式裝置的桌面模式下回應,並顯示最佳化的版面配置。相關使用詳細資料請參閱「讓應用程式適用摺疊式裝置」。

折疊式 Android 裝置如果包含可連接分離或連續顯示面板區域的轉軸,則必須透過 WindowLayoutComponent 向應用程式提供轉軸資訊。

轉軸位置和邊界必須根據已傳遞至 API 的 Context 識別的應用程式視窗來回報。如果應用程式視窗邊界未與轉軸邊界交錯,就不得回報轉軸 DisplayFeature。如果位置無法可靠地回報,例如使用者可在多視窗模式或相容性上下黑邊模式下自由移動應用程式視窗,則也可以選擇不回報顯示功能。

對於折疊功能,當鉸鏈位置在穩定狀態之間變更時,必須回報狀態更新。根據預設,在平面顯示狀態下,API 必須回報 FoldingFeature.State.FLAT。如果裝置硬體可以處於穩定狀態的半摺疊模式,API 必須回報 FoldingFeature.State.HALF_OPENED。API 中沒有關閉狀態,因為在這種情況下,應用程式視窗不會顯示,或無法跨越轉軸邊界。

裝置設定

如要支援摺疊功能實作,原始設備製造商 (OEM) 必須執行下列操作:

  • 設定 device_state_configuration.xml 中的裝置狀態,供 DeviceStateManagerService 使用。請參閱 DeviceStateProviderImpl.java

    如果 DeviceStateProviderDeviceStatePolicy 的預設實作方式不適合裝置,可以使用自訂實作。

  • 按照「擴充功能模組發布」一節的說明啟用擴充功能模組。

  • com.android.internal.R.string.config_display_features 字串資源中指定顯示功能的位置 (通常在裝置疊加中的 frameworks/base/core/res/res/values/config.xml 中)。

    字串的預期格式為:

    <type>-[<left>,<top>,<right>,<bottom>]

    type 可以是 foldhingelefttoprightbottom 的值都是在自然顯示方向顯示畫面座標空間中的整數像素座標。設定字串可包含多個顯示功能,並以半形分號分隔。

    例如:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • 定義 DeviceStateManager 中使用的內部裝置狀態 ID 與傳送給開發人員的公開狀態常數之間的對應關係com.android.internal.R.array.config_device_state_postures

    每個項目的預期格式如下:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    支援的狀態 ID 如下:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1:此狀態沒有可回報的折疊功能。舉例來說,這可以是典型折疊式裝置的關閉狀態,主畫面位於內側。
    • COMMON_STATE_HALF_OPENED = 2:折疊功能處於半開狀態。
    • COMMON_STATE_FLAT = 3:折疊功能是平的。舉例來說,如果是一般摺疊式裝置的開啟狀態,則主畫面位於內側。
    • COMMON_STATE_USE_BASE_STATE = 1000:在 Android 14 中,這個值可用於模擬狀態,此值會使用基本狀態衍生轉軸狀態,如 CommonFoldingFeature.java 所定義

    詳情請參閱 DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int)

    例如:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

窗戶區域

視窗區域元件提供一組功能,可讓應用程式在某些摺疊式裝置和多顯示裝置上存取其他螢幕和顯示區域。

後置顯示模式可讓應用程式在摺疊式裝置的封面螢幕中顯示相機預覽 UI,以便使用主要裝置相機拍攝自拍照和影片。如果裝置具備與 Android 相容 (根據 Android CDD 定義,適用於大小、密度和可用導覽預設用途等屬性) 的封面螢幕,則必須提供與後置裝置相機對齊的封面螢幕。

在 Android 14 中,雙顯示模式可讓應用程式在摺疊式裝置的內螢幕中執行,讓封面螢幕上的其他使用者看見其他內容;例如,封面螢幕可以向拍攝對象顯示相機預覽畫面。

裝置設定

如要支援摺疊功能實作,原始設備製造商 (OEM) 必須執行下列操作:

  • device_state_configuration.xml 中的裝置狀態設為由 DeviceStateManagerService 使用。詳情請參閱 DeviceStateProviderImpl.java

    如果 DeviceStateProviderDeviceStatePolicy 的預設實作方式不適合裝置,可以使用自訂實作。

  • 如果是支援開啟或平面模式的摺疊式裝置,請在 com.android.internal.R.array.config_openDeviceStates 中指定對應的狀態 ID。

  • 如果是支援折疊狀態的折疊式裝置,請在 com.android.internal.R.array.config_foldedDeviceStates 中列出對應的狀態 ID。

  • 如果是支援半折疊狀態的折疊式裝置 (轉軸是打開的半摺疊式筆電),請在 com.android.internal.R.array.config_halfFoldedDeviceStates 中列出對應的狀態。

  • 若是支援後置顯示模式的裝置:

    • 列出 DeviceStateManagercom.android.internal.R.array.config_rearDisplayDeviceStates 中對應狀態。
    • com.android.internal.R.string.config_rearDisplayPhysicalAddress 中指定後置螢幕的實際顯示位址。
    • com.android.internal.R.integer.config_deviceStateRearDisplay 中指定擴充功能要使用的狀態 ID。
    • com.android.internal.R.array.config_deviceStatesAvailableForAppRequests 中新增狀態 ID,讓應用程式可以使用。
  • 在 Android 14 中,如果是支援雙 (並行) 顯示模式的裝置:

    • com.android.internal.R.bool.config_supportsConcurrentInternalDisplays 設為 true
    • 指定後置顯示器的實際顯示地址 (位於 com.android.internal.R.config_deviceStateConcurrentRearDisplay 中)。
    • 如果要讓應用程式使用 ID,請在 com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay 中指定要供擴充功能使用的狀態 ID。
    • com.android.internal.R.array.config_deviceStatesAvailableForAppRequests 中新增狀態 ID,以提供給應用程式。

驗證

原始設備製造商 (OEM) 必須驗證其實作情形,以確保常見情境中的預期行為。原始設備製造商 (OEM) 可使用 CTS 測試和使用 Jetpack WindowManager 的測試來測試實作項目。

CTS 測試

如要執行 CTS 測試,請參閱「執行 CTS 測試」。與 Jetpack WindowManager 相關的 CTS 測試位於 cts/tests/framework/base/windowmanager/jetpack/ 下。測試模組名稱為 CtsWindowManagerJetpackTestCases

WindowManager 測試

如要下載 Jetpack WindowManager 測試,請按照 Android Jetpack 操作說明進行。這些測試位於視窗程式庫中的 window:window 模組下方:window/window/src/androidTest/

如要透過指令列為 window:window 模組執行裝置測試,請執行下列操作:

  1. 接上已啟用開發人員選項和 USB 偵錯功能的裝置。
  2. 允許電腦對裝置偵錯。
  3. 在 androidx 存放區的根目錄中開啟 Shell。
  4. 將目錄變更為 framework/support
  5. 執行下列指令:./gradlew window:window:connectedAndroidTest
  6. 分析結果。

如要透過 Android Studio 執行測試,請按照下列步驟操作:

  1. 開啟 Android Studio。
  2. 接上已啟用開發人員選項和 USB 偵錯功能的裝置。
  3. 允許電腦對裝置偵錯。
  4. 前往視窗模組的視窗程式庫中執行測試。
  5. 開啟測試類別,然後使用編輯器右側的綠色箭頭執行測試。

或者,您也可以在 Android Studio 中建立設定,以便執行測試方法、測試類別或模組中的所有測試。

您可以查看殼層的輸出內容,手動分析結果。如果裝置未達成某些假設,系統會略過部分測試。結果會儲存在標準位置,分析師可以編寫指令碼,自動分析結果。