窗口管理器擴展

Jetpack WindowManager庫使應用程式開發人員能夠支援新的裝置外形尺寸和多視窗環境。

WindowManager 擴充功能 (Extensions) 是一個可選的 Android 平台模組,可啟用各種 Jetpack WindowManager 功能。此模組在frameworks/base/libs/WindowManager/Jetpack中的 AOSP 中實現,並在支援 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 的最早版本相容,但 sidecar 不再積極維護。

下圖展示了確定使用androidx.window.extensionsandroidx.window.sidecar的邏輯。

圖 2.造訪androidx.window.extensionsandroidx.window.sidecar決策樹。

擴充模組

擴展為可折疊大螢幕裝置和支援外部顯示器上的視窗的裝置提供視窗功能。特色領域包括:

如果裝置硬體不支援對應的功能,擴充的 OEM 實作可以提供空元件或具有WindowExtensions介面中方法的預設或存根實作的元件,除非相容性定義文件 (CDD) 7.1.1.1中特別要求該功能。

擴充功能和 Jetpack API

除了公共平台 API 之外,WindowManager 擴充模組還提供自己的 API 介面。擴充模組是在非開發人員的androidx.window.extensions Jetpack 庫中公開開發的,以便 Jetpack WindowManager ( androidx.window ) 可以在編譯時連結到它。擴充 API 表面通常提供較低階的 API。

擴充功能提供的 API 僅供 Jetpack WindowManager 庫使用。擴展 API 不適合由應用程式開發人員直接呼叫。不得將擴充庫新增為 Gradle 建置檔中應用程式的依賴項,以確保正確的功能。避免直接將擴充程式庫預編譯到應用程式中;相反,依靠運行時加載來防止混合加載預編譯和運行時提供的擴展類的情況。

Jetpack WindowManager ( androidx.window ) 旨在作為應用程式依賴項添加,並提供開發人員的公共 API,包括 WindowManager 擴充功能的 API。 WindowManager 程式庫會自動將擴充功能載入到應用程式進程中,並將較低層級的擴充 API 包裝到較高層級的抽象化和更集中的介面中。 WindowManager Jetpack API 遵循現代 Android 應用程式開發標準,旨在透過與使用其他 AndroidX 程式庫的程式碼庫良好整合來提供便利的互通性。

擴充版本和更新

擴充模組可以隨著Android平台每年或每季的更新而更新。每季更新使擴展 API 等級能夠在 Android 平台 API 更新之間提高,從而實現更快的迭代,並為 OEM 提供在硬體發布前添加對新功能的官方 API 存取的機會。

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

安卓平台版本WindowManager 擴充 API 級別androidx.window.extensions API 版本
安卓14 3 1.2.0
安卓 13 QPR3 2 1.1.0
安卓13 1 1.0.0
安卓12L 1 1.0.0

每次對現有穩定 API 表面(右列)進行新增時,擴充 API 等級(中列)都會增加。

向後和向前相容性

Jetpack WindowManager 可以處理頻繁 API 等級更新、快速 API 演進和向後相容性的複雜性。當程式庫程式碼在應用程式進程中執行時,程式庫會檢查聲明的擴展 API 級別,並根據聲明的級別提供對功能的存取。

為了防止應用程式在執行時間崩潰,WindowManager 也會根據宣告的擴充 API 等級對可用擴充 API 執行執行階段 Java 反射檢查。如果不匹配,WindowManager 可以(部分或完全)停用擴展,並將相關功能報告為應用程式不可用。

WindowManager 擴充功能是作為system_ext模組實現,該模組在擴充功能的實作中使用私有平台 API 呼叫 WindowManager 核心、 DeviceStateManager和其他系統服務。

在相應的季度或年度 Android 平台版本最終確定之前,可能無法保持與擴展的預發布版本的兼容性。擴充 API 的完整歷史記錄可以在發布分支window:extensions:extensions API 文字檔案中找到。

較新版本的擴充功能必須繼續與編譯到應用程式中的舊版本 WindowManager 一起使用,以保持向前相容性。為了確保這一點,任何新版本的擴充 API 只會新增新的 API,而不會刪除舊的 API。因此,具有較舊 WindowManager 版本的應用程式可以繼續使用應用程式編譯時所針對的較舊擴充 API。

CTS 驗證可確保對於裝置上任何聲明的擴充 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中使用的內部裝置狀態識別碼與com.android.internal.R.array.config_device_state_postures中傳送給開發人員的公共狀態常數之間的對應。

    每個條目的預期格式為:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    支援的狀態標識符是:

    • 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中指定對應的狀態識別碼。

  • 對於支援折疊狀態的折疊設備,請在com.android.internal.R.array.config_foldedDeviceStates中列出對應的狀態識別碼。

  • 對於支援半折疊狀態的折疊裝置(鉸鏈像筆記型電腦一樣半打開),請在com.android.internal.R.array.config_halfFoldedDeviceStates中列出相應的狀態。

  • 對於支援後置顯示模式的設備:

    • com.android.internal.R.array.config_rearDisplayDeviceStates中列出DeviceStateManager的對應狀態。
    • com.android.internal.R.string.config_rearDisplayPhysicalAddress中指定後置顯示器的實體顯示位址。
    • com.android.internal.R.integer.config_deviceStateRearDisplay中指定擴充要使用的狀態識別碼。
    • com.android.internal.R.array.config_deviceStatesAvailableForAppRequests中新增狀態識別碼以使其可供應用程式使用。
  • 在 Android 14 上,對於支援雙(並發)顯示模式的裝置:

    • com.android.internal.R.bool.config_supportsConcurrentInternalDisplays設為true
    • com.android.internal.R.config_deviceStateConcurrentRearDisplay中指定後置顯示器的實體顯示位址。
    • 如果識別碼可供應用程式使用,請在com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay中指定擴充功能要使用的狀態識別碼。
    • com.android.internal.R.array.config_deviceStatesAvailableForAppRequests中新增狀態識別碼以使其可供應用程式使用。

確認

OEM 必須驗證其實施,以確保常見場景中的預期行為。 OEM 可以使用 CTS 測試和使用 Jetpack WindowManager 的測試來測試實作。

CTS測試

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

視窗管理器測試

若要下載 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 中建立配置來執行測試方法、測試類別或模組中的所有測試。

可以透過查看 shell 的輸出來手動分析結果。如果設備不符合某些假設,則會跳過某些測試。結果保存在標準位置,分析人員可以編寫腳本來自動分析結果。