WindowManager-Erweiterungsmodul

Mit der Jetpack WindowManager Bibliothek können App-Entwickler neue Geräteformfaktoren und Mehrfenstermodus-Umgebungen unterstützen.

WindowManager Extensions (Erweiterungen) ist ein optionales Android-Plattformmodul, das eine Vielzahl von Jetpack WindowManager-Funktionen ermöglicht. Das Modul ist implementiert in AOSP in frameworks/base/libs/WindowManager/Jetpack und wird auf Geräten ausgeliefert, die die WindowManager-Funktionen unterstützen.

Verteilung des Erweiterungsmoduls

Erweiterungen werden in eine JAR-Bibliothek kompiliert und in der Partition system_ext auf einem Gerät platziert, wenn Erweiterungen in der Make-Datei des Geräts aktiviert sind.

Wenn Sie Erweiterungen auf einem Gerät aktivieren möchten, fügen Sie der Make-Datei des Produktgeräts Folgendes hinzu:

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

Dadurch werden die Pakete androidx.window.extensions und androidx.window.sidecar auf dem Gerät aktiviert und die Property persist.wm.extensions.enabled festgelegt. Wenn Sie diese Pakete in die Make-Datei einfügen, werden auch Deklarationen in etc/permissions/ platziert, sodass sie für App-Prozesse verfügbar sind. Normalerweise werden die Module zur Laufzeit in den App-Prozess geladen und als Teil davon ausgeführt, wenn sie von der Jetpack WindowManager-Bibliothek verwendet werden. Dadurch ähnelt ihre Funktionsweise dem clientseitigen Framework-Code, wie in der folgenden Abbildung dargestellt:

WindowManager-Erweiterungen werden ähnlich wie Plattformcode in den App-Prozess geladen.

Abbildung 1 : Erweiterungen, die in den App-Prozess geladen wurden.

Das Modul androidx.window.extensions ist das aktuelle Erweiterungsmodul, das aktiv weiterentwickelt wird. Das Modul androidx.window.sidecar ist ein älteres Modul, das zur Kompatibilität mit den frühesten Versionen von Jetpack WindowManager enthalten ist. Sidecar wird jedoch nicht mehr aktiv gewartet.

Die folgende Abbildung zeigt die Logik zur Bestimmung der Verwendung von androidx.window.extensions oder androidx.window.sidecar.

Entscheidungsbaum für den Zugriff auf androidx.window.extensions oder androidx.window.sidecar

Abbildung 2 : Entscheidungsbaum für den Zugriff auf androidx.window.extensions oder androidx.window.sidecar.

Erweiterungsmodule

Erweiterungen bieten Fensterfunktionen für faltbare Geräte mit großem Display und Geräte, die Fensterfunktionen auf externen Displays unterstützen. Zu den Funktionsbereichen gehören:

OEM-Implementierungen von Erweiterungen können Null-Komponenten oder Komponenten mit Standard- oder Stub-Implementierungen der Methoden in der WindowExtensions Schnittstelle bereitstellen, wenn die Gerätehardware die entsprechenden Funktionen nicht unterstützt. Dies gilt nicht, wenn die Funktion in Compatibility Definition Document (CDD) 7.1.1.1 ausdrücklich angefordert wird.

Erweiterungen und Jetpack APIs

Das WindowManager Extensions-Modul bietet neben den öffentlichen Plattform-APIs eine eigene API-Oberfläche. Das Erweiterungsmodul wird öffentlich in einer nicht entwicklerorientierten androidx.window.extensions Jetpack-Bibliothek entwickelt, sodass Jetpack WindowManager (androidx.window) es zur Kompilierzeit verknüpfen kann. Die API-Oberfläche für Erweiterungen bietet in der Regel APIs auf niedrigerer Ebene.

Die von Erweiterungen bereitgestellten APIs sind nur für die Verwendung durch die Jetpack WindowManager-Bibliothek vorgesehen. Die Erweiterungs-APIs sind nicht für den direkten Aufruf durch App-Entwickler vorgesehen. Die Erweiterungsbibliothek darf in der Gradle-Build-Datei nicht als Abhängigkeit für eine App hinzugefügt werden, um die korrekte Funktion zu gewährleisten. Vermeiden Sie es, die Erweiterungsbibliothek direkt in eine App zu vorkompilieren. Verwenden Sie stattdessen das Laden zur Laufzeit, um zu verhindern, dass eine Mischung aus vorkompilierten und zur Laufzeit bereitgestellten Erweiterungsklassen geladen wird.

Jetpack WindowManager (androidx.window) sollte als App-Abhängigkeit hinzugefügt werden und bietet die öffentlichen, entwicklerorientierten APIs, einschließlich der APIs für WindowManager Extensions-Funktionen. Die WindowManager-Bibliothek lädt Erweiterungen automatisch in den App-Prozess und umschließt die Erweiterungs-APIs auf niedrigerer Ebene mit Abstraktionen auf höherer Ebene und gezielteren Schnittstellen. Die WindowManager Jetpack APIs entsprechen den Standards der modernen Android-App-Entwicklung und sollen eine komfortable Interoperabilität ermöglichen, indem sie gut in Codebasen integriert werden, die andere AndroidX-Bibliotheken verwenden.

Erweiterungsversionen und ‑updates

Das Erweiterungsmodul kann mit den jährlichen oder vierteljährlichen Updates der Android-Plattform aktualisiert werden. Mit vierteljährlichen Updates kann das API-Level für Erweiterungen zwischen den API-Updates der Android-Plattform erhöht werden. So sind schnellere Iterationen möglich und OEMs können offiziellen API-Zugriff auf neue Funktionen in der Nähe von Hardware-Releases hinzufügen.

In der folgenden Tabelle sind die androidx.window.extensions-API-Versionen für verschiedene Android-Releases aufgeführt.

Android-Plattformversion WindowManager Extensions API-Level androidx.window.extensions API-Version
Android 15 6 1.5.0 (bald verfügbar)
Android 14 QPR3 5 1.4.0 (bald verfügbar)
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

Das API-Level für Erweiterungen (mittlere Spalte) wird jedes Mal erhöht, wenn die vorhandene stabile API-Oberfläche (rechte Spalte) erweitert wird.

Abwärts- und Vorwärtskompatibilität

Jetpack WindowManager kümmert sich um die Komplexität, die mit häufigen API-Level-Updates, der schnellen API-Entwicklung und der Abwärtskompatibilität verbunden ist. Wenn der Bibliothekscode im App-Prozess ausgeführt wird, prüft die Bibliothek das deklarierte API-Level für Erweiterungen und bietet Zugriff auf Funktionen entsprechend dem deklarierten Level.

Um zu verhindern, dass eine App zur Laufzeit abstürzt, führt WindowManager auch eine Java-Reflektionsprüfung der verfügbaren Erweiterungs-APIs gemäß dem deklarierten API-Level für Erweiterungen durch. Bei einer Abweichung kann WindowManager die Verwendung von Erweiterungen (teilweise oder vollständig) deaktivieren und die entsprechenden Funktionen als für die App nicht verfügbar melden.

WindowManager Extensions werden als system_ext Modul implementiert, das private Plattform-APIs verwendet, um WindowManager-Kern, DeviceStateManager, und andere Systemdienste in der Implementierung der Erweiterungsfunktionen aufzurufen.

Die Kompatibilität wird möglicherweise nicht mit Vorabversionen von Erweiterungen vor dem entsprechenden vierteljährlichen oder jährlichen Android-Plattform-Release beibehalten, mit dem die Versionen abgeschlossen werden. Die vollständige Historie der Erweiterungs-APIs kann in den API-Textdateien des Release-Branchs window:extensions:extensionsgefunden werden.

Neuere Versionen von Erweiterungen müssen weiterhin mit niedrigeren Versionen von WindowManager funktionieren, die in Apps kompiliert wurden, um die Vorwärtskompatibilität zu gewährleisten. Dazu werden in jeder neuen Version der Erweiterungs-API nur neue APIs hinzugefügt und keine älteren entfernt. So können Apps mit niedrigeren WindowManager-Versionen weiterhin die älteren Erweiterungs-APIs verwenden, mit denen die Apps kompiliert wurden.

Die CTS-Überprüfung stellt sicher, dass für jede deklarierte Version von Erweiterungs-APIs auf dem Gerät alle APIs für diese und frühere Versionen vorhanden und funktionsfähig sind.

Leistung

Das Erweiterungsmodul wird ab Android 14 (API-Level 34) standardmäßig in System-Class-Loadern ohne Boot-Classpath zwischengespeichert. Daher gibt es keine Leistungseinbußen durch das Laden des Moduls in den Arbeitsspeicher beim Start der App. Die Verwendung einzelner Modulfunktionen kann sich geringfügig auf die Leistungseigenschaften von Apps auswirken, wenn zusätzliche IPC-Aufrufe zwischen Client und Server ausgeführt werden.

Module

Aktivitätseinbettung

Mit der Komponente für die Aktivitätseinbettung können Apps ihre UI für Geräte mit großem Display und externe Displays optimieren. Die Aktivitätseinbettung ermöglicht die Darstellung von zwei Aktivitäten nebeneinander in einem Layout mit mehreren Bereichen und erleichtert so die adaptive App-Entwicklung für ältere Apps.

Die Komponente für die Aktivitätseinbettung muss auf allen Geräten mit einem integrierten Display mit einer Größe von mindestens sw600dp verfügbar sein. Die Aktivitätseinbettung muss auch auf Geräten aktiviert sein, die externe Displayverbindungen unterstützen, da die App möglicherweise größer angezeigt wird, wenn zur Laufzeit externe Displays angeschlossen sind.

Gerätekonfiguration

Neben der Aktivierung des Erweiterungs moduls, wie im Abschnitt Erweiterungsmodul Verteilung beschrieben, ist keine spezielle Gerätekonfiguration erforderlich. Es ist sinnvoll, Erweiterungen auf allen Geräten zu aktivieren, die den Mehrfenstermodus unterstützen. In zukünftigen Android-Versionen werden Erweiterungen wahrscheinlich für gängige Konfigurationen von Handheld-Geräten und Geräten mit großem Display erforderlich sein.

Informationen zum Fensterlayout

Die Komponente für Informationen zum Fensterlayout ermittelt die Position und den Status des Scharniers auf einem faltbaren Gerät, wenn das Scharnier ein App-Fenster kreuzt. Mit Informationen zum Fensterlayout können Apps im Tablet-Modus auf faltbaren Geräten reagieren und optimierte Layouts anzeigen. Details zur Verwendung finden Sie unter App für faltbare Geräte optimieren.

Faltbare Android-Geräte mit einem Scharnier, das separate oder durchgehende Displaybereiche verbindet, müssen die Informationen zum Scharnier über WindowLayoutComponentfür Apps verfügbar machen.

Die Position und die Grenzen des Scharniers müssen relativ zum App-Fenster angegeben werden, das durch einen Context identifiziert wird, der an die API übergeben wird. Wenn sich die Grenzen des App-Fensters nicht mit den Grenzen des Scharniers überschneiden, darf das Scharnier DisplayFeature nicht gemeldet werden. Es ist auch akzeptabel, die Displayfunktionen nicht zu melden, wenn ihre Position nicht zuverlässig gemeldet werden kann, z. B. wenn ein App-Fenster im Mehrfenstermodus oder im Kompatibilitätsmodus mit Letterboxing frei vom Nutzer verschoben werden kann.

Bei Faltfunktionen, müssen die Statusupdates gemeldet werden, wenn sich die Position des Scharniers zwischen den stabilen Zuständen ändert. Standardmäßig muss die API im flachen Displayzustand FoldingFeature.State.FLAT melden. Wenn die Gerätehardware in einem stabilen Zustand halb gefaltet bleiben kann, muss die API FoldingFeature.State.HALF_OPENED melden. In der API gibt es keinen geschlossenen Zustand, da das App-Fenster in diesem Fall entweder nicht sichtbar wäre oder die Grenzen des Scharniers nicht kreuzen würde.

Gerätekonfiguration

Um die Implementierung der Faltfunktion zu unterstützen, müssen OEMs Folgendes tun:

  • Konfigurieren Sie die Gerätezustände in device_state_configuration.xml, die von DeviceStateManagerService verwendet werden sollen. Eine Referenz finden Sie unter DeviceStateProviderImpl.java.

    Wenn die Standardimplementierungen von DeviceStateProvider oder DeviceStatePolicy nicht für das Gerät geeignet sind, kann eine benutzerdefinierte Implementierung verwendet werden.

  • Aktivieren Sie das Erweiterungsmodul, wie im Abschnitt Verteilung des Erweiterungsmoduls beschrieben.

  • Geben Sie die Position der Displayfunktionen in der String-Ressource com.android.internal.R.string.config_display_features an (normalerweise in frameworks/base/core/res/res/values/config.xml im Geräte-Overlay).

    Das erwartete Format für den String ist:

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

    Der type kann entweder fold oder hinge sein. Die Werte für left, top, right und bottom sind ganzzahlige Pixelkoordinaten im Koordinatensystem des Displays in der natürlichen Ausrichtung des Displays. Der Konfigurationsstring kann mehrere Displayfunktionen enthalten, die durch Semikolons getrennt sind.

    Beispiel:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Definieren Sie die Zuordnung zwischen den internen Geräte-ID-Zuständen, die in DeviceStateManager verwendet werden, und den öffentlichen Zustandskonstanten, die an Entwickler in com.android.internal.R.array.config_device_state_postures gesendet werden.

    Das erwartete Format für jeden Eintrag ist:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Die unterstützten Zustands-IDs sind:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: Für diesen Zustand sind keine Faltfunktionen zu melden. Beispielsweise kann es sich um den geschlossenen Zustand des typischen nach innen faltbaren Geräts handeln, bei dem sich das Hauptdisplay auf der Innenseite befindet.
    • COMMON_STATE_HALF_OPENED = 2: Die Faltfunktion ist halb geöffnet.
    • COMMON_STATE_FLAT = 3: Die Faltfunktion ist flach. Beispielsweise kann es sich um den geöffneten Zustand des typischen nach innen faltbaren Geräts handeln, bei dem sich das Hauptdisplay auf der Innenseite befindet.
    • COMMON_STATE_USE_BASE_STATE = 1000: In Android 14 ein Wert, der für emulierte Zustände verwendet werden kann, bei denen der Zustand des Scharniers aus dem Basiszustand abgeleitet wird, wie in CommonFoldingFeature.javadefiniert.

    Weitere Informationen finden Sie unter DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int).

    Beispiel:

    <!-- 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>
    

Fensterbereich

Die Komponente für den Fensterbereich bietet eine Reihe von Funktionen, mit denen Apps auf einigen faltbaren Geräten und Geräten mit mehreren Displays auf zusätzliche Displays und Displaybereiche zugreifen können.

Im Modus für das hintere Display kann eine App die UI der Kameravorschau auf dem Frontdisplay eines faltbaren Geräts anzeigen, damit die Hauptkamera des Geräts für Selfies und Videos verwendet werden kann. Geräte mit einem Android-kompatiblen Frontdisplay (gemäß Android CDD in Bezug auf Attribute wie Größe, Dichte und verfügbare Navigationshilfen), das mit den hinteren Kameras des Geräts übereinstimmt, müssen Zugriff auf den Modus für das hintere Display bieten.

Unter Android 14 können Apps, die auf dem inneren Display eines faltbaren Geräts ausgeführt werden, im Dual-Display-Modus zusätzliche Inhalte auf dem Frontdisplay anzeigen, das anderen Nutzern zugewandt ist. Auf dem Frontdisplay kann beispielsweise die Kameravorschau für die Person angezeigt werden, die fotografiert oder aufgenommen wird.

Gerätekonfiguration

Um die Implementierung der Faltfunktion zu unterstützen, müssen OEMs Folgendes tun:

  • Konfigurieren Sie die Gerätezustände in device_state_configuration.xml, die von DeviceStateManagerService verwendet werden sollen. Weitere Informationen finden Sie unter DeviceStateProviderImpl.java.

    Wenn die Standardimplementierung von DeviceStateProvider oder DeviceStatePolicy nicht für das Gerät geeignet ist, kann eine benutzerdefinierte Implementierung verwendet werden.

  • Geben Sie für faltbare Geräte, die den geöffneten oder flachen Modus unterstützen, die entsprechenden Zustands-IDs in com.android.internal.R.array.config_openDeviceStates an.

  • Listen Sie für nach innen faltbare Geräte, die gefaltete Zustände unterstützen, die entsprechenden Zustands-IDs in com.android.internal.R.array.config_foldedDeviceStates auf.

  • Listen Sie für nach innen faltbare Geräte, die einen halb gefalteten Zustand unterstützen (Scharnier ist halb geöffnet wie bei einem Laptop), die entsprechenden Zustände in com.android.internal.R.array.config_halfFoldedDeviceStates auf.

  • Für Geräte, die den Modus für das hintere Display unterstützen:

    • Listen Sie die entsprechenden Zustände in com.android.internal.R.array.config_rearDisplayDeviceStates für DeviceStateManager auf.
    • Geben Sie die physische Displayadresse des hinteren Displays in com.android.internal.R.string.config_rearDisplayPhysicalAddress an.
    • Geben Sie die Zustands-ID in com.android.internal.R.integer.config_deviceStateRearDisplay an, die von Erweiterungen verwendet werden soll.
    • Fügen Sie die Zustands-ID in com.android.internal.R.array.config_deviceStatesAvailableForAppRequests hinzu, um sie für Apps verfügbar zu machen.
  • Unter Android 14 für Geräte, die den Dual-Display-Modus (gleichzeitig) unterstützen:

    • Legen Sie com.android.internal.R.bool.config_supportsConcurrentInternalDisplays auf true fest.
    • Geben Sie die physische Displayadresse des hinteren Displays in com.android.internal.R.config_deviceStateConcurrentRearDisplay an.
    • Geben Sie die Zustands-ID in com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay an, die von Erweiterungen verwendet werden soll, wenn die ID für Apps verfügbar gemacht werden soll.
    • Fügen Sie die Zustands-ID in com.android.internal.R.array.config_deviceStatesAvailableForAppRequests hinzu, um sie für Apps verfügbar zu machen.

Bestätigung

OEMs müssen ihre Implementierungen überprüfen, um das erwartete Verhalten in gängigen Szenarien zu gewährleisten. CTS-Tests und Tests mit Jetpack WindowManager stehen OEMs zum Testen von Implementierungen zur Verfügung.

CTS-Tests

Informationen zum Ausführen der CTS-Tests finden Sie unter CTS-Tests ausführen. Die CTS Tests für Jetpack WindowManager finden Sie unter cts/tests/framework/base/windowmanager/jetpack/. Der Name des Testmoduls ist CtsWindowManagerJetpackTestCases.

WindowManager-Tests

Informationen zum Herunterladen der Jetpack WindowManager-Tests finden Sie unter Android Jetpack.

Die Tests befinden sich in der Window-Bibliothek unter dem window:window Modul: window/window/src/androidTest/.

So führen Sie die Gerätetests für das Modul window:window über die Befehlszeile aus:

  1. Schließen Sie ein Gerät an, auf dem die Entwickleroptionen und das USB-Debugging aktiviert sind.
  2. Erlauben Sie dem Computer, das Gerät zu debuggen.
  3. Öffnen Sie eine Shell im Stammverzeichnis des androidx-Repositorys.
  4. Ändern Sie das Verzeichnis in framework/support.
  5. Führen Sie den Befehl ./gradlew window:window:connectedAndroidTest aus.
  6. Analysieren Sie die Ergebnisse.

So führen Sie die Tests in Android Studio aus:

  1. Öffnen Sie Android Studio.
  2. Schließen Sie ein Gerät an, auf dem die Entwickleroptionen und das USB-Debugging aktiviert sind.
  3. Erlauben Sie dem Computer, das Gerät zu debuggen.
  4. Rufen Sie einen Test in der Window-Bibliothek des Window-Moduls auf.
  5. Öffnen Sie eine Testklasse und führen Sie sie mit den grünen Pfeilen auf der rechten Seite des Editors aus.

Alternativ können Sie in Android Studio eine Konfiguration erstellen, um eine Testmethode, eine Testklasse oder alle Tests in einem Modul auszuführen.

Die Ergebnisse können manuell analysiert werden, indem Sie sich die Ausgabe der Shell ansehen. Einige Tests werden übersprungen, wenn das Gerät bestimmte Voraussetzungen nicht erfüllt. Die Ergebnisse werden an einem Standardspeicherort gespeichert und Analysten können ein Skript schreiben, um die Analyse der Ergebnisse zu automatisieren.