WindowManager-Erweiterungen

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

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

Verteilung von Erweiterungsmodulen

Erweiterungen werden in eine .jar-Bibliothek kompiliert und in der system_ext-Partition auf einem Gerät abgelegt, wenn Erweiterungen im Geräte-Makefile aktiviert sind.

Wenn Sie Erweiterungen auf einem Gerät aktivieren möchten, fügen Sie der Produkt-Gerätemakefile 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 Eigenschaft persist.wm.extensions.enabled festgelegt. Wenn Sie diese Pakete in das Makefile aufnehmen, werden auch Deklarationen in etc/permissions/ platziert, wodurch sie für Anwendungsprozesse verfügbar sind. Normalerweise werden die Module bei der Verwendung durch die Jetpack WindowManager-Bibliothek zur Laufzeit im Rahmen des Anwendungsprozesses geladen und ausgeführt. Dadurch ähnelt ihre Funktionsweise dem clientseitigen Framework-Code, wie in der folgenden Abbildung dargestellt:

Abbildung 1. WindowManager-Erweiterungen, die ähnlich wie Plattformcode in den Anwendungsvorgang geladen werden.

Das androidx.window.extensions-Modul ist das aktuelle Erweiterungsmodul, das sich in aktiver Entwicklungsphase befindet. Das androidx.window.sidecar-Modul ist ein älteres Modul, das für die Kompatibilität mit den frühesten Versionen von Jetpack WindowManager enthalten ist. Das Sidecar wird jedoch nicht mehr aktiv gepflegt.

Die folgende Abbildung zeigt die Logik zur Bestimmung der Verwendung von 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 Fenster auf externen Displays unterstützen. Zu den Funktionsbereichen gehören:

OEM-Implementierungen von Erweiterungen können Nullkomponenten oder Komponenten mit Standard- oder Stub-Implementierungen der Methoden in der WindowExtensions-Benutzeroberfläche bereitstellen, wenn die Gerätehardware die entsprechenden Funktionen nicht unterstützt, es sei denn, die Funktion wird im Compatibility Definition Document (CDD) 7.1.1.1 ausdrücklich angefordert.

Erweiterungen und Jetpack-APIs

Das WindowManager Extensions-Modul bietet zusätzlich zu den öffentlichen Plattform-APIs eine eigene API-Oberfläche. Das Erweiterungsmodul wird öffentlich in einer nicht für Entwickler bestimmten androidx.window.extensions-Jetpack-Bibliothek entwickelt, damit Jetpack WindowManager (androidx.window) zur Kompilierungszeit damit verknüpft werden kann. Die Extensions API-Oberfläche bietet in der Regel APIs der unteren Ebene.

Die von Erweiterungen bereitgestellten APIs dürfen nur von der Jetpack WindowManager-Bibliothek verwendet werden. Die Erweiterungs-APIs sind nicht für den direkten Aufruf durch App-Entwickler gedacht. Die Erweiterungsbibliothek darf nicht als Abhängigkeit für eine Anwendung in der Gradle-Builddatei hinzugefügt werden, damit sie ordnungsgemäß funktioniert. Vermeiden Sie es, die Erweiterungsbibliothek direkt in eine Anwendung zu kompilieren. 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) wird als Anwendungsabhängigkeit hinzugefügt und bietet die öffentlichen APIs für Entwickler, einschließlich der APIs für WindowManager-Erweiterungen. Die WindowManager-Bibliothek lädt Erweiterungen automatisch in den Anwendungsvorgang und verpackt die Extensions APIs der unteren Ebene in Abstraktionsebenen höherer Ebene und in spezifischere Schnittstellen. Die WindowManager Jetpack APIs entsprechen den Standards der modernen Android-Anwendungsentwicklung und sollen eine einfache Interoperabilität bieten, da sie sich gut in Codebases integrieren lassen, in denen andere AndroidX-Bibliotheken verwendet werden.

Versionen und Updates von Erweiterungen

Das Erweiterungsmodul kann zusammen mit der Android-Plattform jährlich oder vierteljährlich aktualisiert werden. Durch vierteljährliche Updates kann das Level der Extensions API zwischen den API-Updates der Android-Plattform erhöht werden. So können OEMs schneller iterieren und neuen Funktionen kurz vor der Markteinführung der Hardware offiziellen API-Zugriff hinzufügen.

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

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

Die API-Ebene der 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 bewältigt die Komplexität häufiger Updates auf API-Ebene, die schnelle API-Entwicklung und die Abwärtskompatibilität. Wenn der Bibliothekcode im Anwendungsvorgang ausgeführt wird, prüft die Bibliothek die deklarierte Extensions API-Ebene und gewährt Zugriff auf Funktionen gemäß der deklarierten Ebene.

Um eine Anwendung vor Abstürzen zur Laufzeit zu schützen, führt WindowManager außerdem eine Java-Reflexionsprüfung der verfügbaren Extensions APIs gemäß der angegebenen Extensions API-Ebene durch. Bei einer Abweichung kann WindowManager die Verwendung von Erweiterungen teilweise oder vollständig deaktivieren und die entsprechenden Funktionen als für die Anwendung nicht verfügbar melden.

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

Die Kompatibilität mit Vorabversionen von Erweiterungen vor dem entsprechenden vierteljährlichen oder jährlichen Android-Plattformrelease, mit dem die Versionen fertiggestellt werden, kann nicht gewährleistet werden. Der vollständige Verlauf der Erweiterungs-APIs befindet sich in den API-Textdateien window:extensions:extensions im Release-Branch.

Neuere Versionen von Erweiterungen müssen weiterhin mit älteren Versionen von WindowManager funktionieren, die in Anwendungen kompiliert wurden, um die Zukunftssicherheit zu gewährleisten. Dazu werden in jeder neuen Version der Extensions API nur neue APIs hinzugefügt und ältere nicht entfernt. Daher können Anwendungen mit älteren WindowManager-Versionen weiterhin die älteren Extensions APIs verwenden, mit denen die Apps kompiliert wurden.

Bei der CTS-Überprüfung wird sichergestellt, dass für jede deklarierte Version der Erweiterungs-APIs auf dem Gerät alle APIs für diese und die vorherigen Versionen vorhanden und funktionsfähig sind.

Leistung

Das Erweiterungsmodul wird ab Android 14 (API-Level 34) standardmäßig in System-Klassenladern ohne Bootclasspath im Cache gespeichert. Das Laden des Moduls in den Arbeitsspeicher beim Starten der App hat daher keine Auswirkungen auf die Leistung. Die Verwendung einzelner Modulfunktionen kann sich geringfügig auf die Leistungsmerkmale von Apps auswirken, wenn zusätzliche IPC-Aufrufe zwischen dem Client und dem Server ausgeführt werden.

Module

Aktivitätseinbettung

Mit der Komponente Aktivitäts-Embedding können Entwickler die Benutzeroberfläche ihrer Apps für Geräte mit großem Bildschirm und externe Displays optimieren. Durch das Einbetten von Aktivitäten können zwei Aktivitäten in einem mehrflügeligen Layout nebeneinander präsentiert werden, was die Entwicklung adaptiver Apps für ältere Anwendungen erleichtert.

Die Komponente zum Einbetten von Aktivitäten muss auf allen Geräten verfügbar sein, die ein integriertes Display mit einer Größe von mindestens sw600dp mm haben. Die Einbettung von Aktivitäten muss auch auf Geräten aktiviert sein, die Verbindungen zu externen Displays unterstützen, da die Anwendung möglicherweise in einer größeren Größe angezeigt wird, wenn externe Displays zur Laufzeit verbunden werden.

Gerätekonfiguration

Es ist keine spezielle Gerätekonfiguration erforderlich, außer dass das Erweiterungsmodul wie im Abschnitt Verteilung des Erweiterungsmoduls beschrieben aktiviert werden muss. Es ist sinnvoll, Erweiterungen auf allen Geräten zu aktivieren, die den Multifenstermodus unterstützen. Bei zukünftigen Android-Versionen sind Erweiterungen wahrscheinlich für gängige Konfigurationen von Mobilgeräten und Geräten mit großem Display erforderlich.

Informationen zum Fensterlayout

Die Information zur Fensteransicht gibt die Position und den Status des Scharniers auf einem faltbaren Gerät an, wenn das Scharnier ein Anwendungsfenster kreuzt. Mit Informationen zum Fensterlayout können Anwendungen auf faltbaren Geräten auf den Modus „Auf dem Tisch“ reagieren und optimierte Layouts anzeigen. Weitere Informationen zur Verwendung finden Sie unter Ihre App für das Zusammenklappen von Geräten optimieren.

Bei faltbaren Android-Geräten mit einem Scharnier, das separate oder zusammenhängende Bereiche des Displaypanels verbindet, müssen die Informationen zum Scharnier für Anwendungen über WindowLayoutComponent verfügbar gemacht werden.

Die Scharnierposition und die Begrenzungen müssen relativ zum Anwendungsfenster angegeben werden, das durch ein Context identifiziert wird, das an die API übergeben wird. Wenn sich die Begrenzungen des Anwendungsfensters nicht mit den Begrenzungen des Scharniers überschneiden, darf das Scharnier DisplayFeature nicht gemeldet werden. Es ist auch zulässig, die Displayfunktionen nicht anzugeben, wenn ihre Position möglicherweise nicht zuverlässig angegeben werden kann, z. B. wenn ein Anwendungsfenster vom Nutzer im Mehrfenstermodus oder im Letterbox-Modus für die Kompatibilität frei verschoben werden kann.

Bei Klappfunktionen müssen die Statusaktualisierungen gemeldet werden, wenn sich die Scharnierposition zwischen den stabilen Status ändert. Im flachen Anzeigestatus muss die API standardmäßig FoldingFeature.State.FLAT zurückgeben. Wenn die Gerätehardware im halbgefalteten Modus in einem stabilen Zustand bleiben kann, muss die API FoldingFeature.State.HALF_OPENED melden. In der API gibt es keinen geschlossenen Status, da das Anwendungsfenster in einem solchen Fall entweder nicht sichtbar wäre oder die Scharniergrenzen nicht überschreiten würde.

Gerätekonfiguration

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

  • Konfigurieren Sie die Gerätestatus in device_state_configuration.xml für die Verwendung durch DeviceStateManagerService. Weitere Informationen 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 den Speicherort der Anzeigefunktionen in der Stringressource 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>]

    type kann entweder fold oder hinge sein. Die Werte für left, top, right und bottom sind Ganzzahlpixelkoordinaten im Displaykoordinatenraum in der natürlichen Displayausrichtung. Der Konfigurationsstring kann mehrere Anzeigefunktionen enthalten, die durch Semikolons getrennt sind.

    Beispiel:

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

    Das erwartete Format für jeden Eintrag lautet:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Folgende Ausweisdokumente werden unterstützt:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: Im Bundesstaat gibt es keine Faltfunktionen, die gemeldet werden können. Das kann beispielsweise der geschlossene Zustand eines typischen faltbaren Geräts mit dem Hauptdisplay auf der Innenseite sein.
    • COMMON_STATE_HALF_OPENED = 2: Die Faltfunktion ist halb geöffnet.
    • COMMON_STATE_FLAT = 3: Die Faltfunktion ist flach. Das kann beispielsweise der geöffnete Zustand eines typischen faltbaren Geräts mit dem Hauptdisplay auf der Innenseite sein.
    • COMMON_STATE_USE_BASE_STATE = 1000: In Android 14 ein Wert, der für emulierte Status verwendet werden kann, bei denen der Scharnierstatus anhand des Basisstatus abgeleitet wird, wie in CommonFoldingFeature.java definiert.

    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 „Fensterbereich“ bietet eine Reihe von Funktionen, die Anwendungen auf einigen faltbaren und mehrbildschirmigen Geräten Zugriff auf zusätzliche Displays und Displaybereiche gewähren.

Im Rückkameramodus kann eine App die Benutzeroberfläche der Kameravorschau auf dem Cover-Display eines faltbaren Geräts anzeigen, um die Hauptkamera des Geräts für Selfies und Videos zu verwenden. Geräte mit einem Android-kompatiblen (gemäß der Android-CDD-Definition in Bezug auf Attribute wie Größe, Dichte und verfügbare Navigationselemente) Cover-Display, das mit den Rückkameras des Geräts übereinstimmt, müssen Zugriff auf den Modus für das Rückkamera-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 Cover-Display anzeigen, das anderen Nutzern zugewandt ist. So kann beispielsweise die Kameravorschau auf dem Cover-Display für die Person angezeigt werden, die fotografiert oder aufgenommen wird.

Gerätekonfiguration

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

  • Konfigurieren Sie die Gerätestatus in device_state_configuration.xml für die Verwendung durch DeviceStateManagerService. 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 Modus „Aufgeklappt“ oder „Zu“ unterstützen, die entsprechenden Status-IDs in com.android.internal.R.array.config_openDeviceStates an.

  • Geben Sie für faltbare Geräte, die zusammengeklappte Zustände unterstützen, die entsprechenden Status-IDs in com.android.internal.R.array.config_foldedDeviceStates an.

  • Geben Sie für faltbare Geräte, die einen halbgefalteten Zustand unterstützen (das Scharnier ist wie bei einem Laptop halb geöffnet), die entsprechenden Status in com.android.internal.R.array.config_halfFoldedDeviceStates an.

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

    • Geben Sie die entsprechenden Status in com.android.internal.R.array.config_rearDisplayDeviceStates für DeviceStateManager an.
    • Geben Sie in com.android.internal.R.string.config_rearDisplayPhysicalAddress die physische Displayadresse des Rückdisplays an.
    • Geben Sie in com.android.internal.R.integer.config_deviceStateRearDisplay die Status-ID an, die von Erweiterungen verwendet werden soll.
    • Fügen Sie die Status-ID in com.android.internal.R.array.config_deviceStatesAvailableForAppRequests hinzu, um sie für Anwendungen verfügbar zu machen.
  • Unter Android 14 auf Geräten mit Dual Screen-Modus (gleichzeitiger Modus):

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

Bestätigung

OEMs müssen ihre Implementierungen prüfen, um das erwartete Verhalten in gängigen Szenarien sicherzustellen. 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 lautet CtsWindowManagerJetpackTestCases.

WindowManager-Tests

Folgen Sie der Anleitung für Android Jetpack, um die Jetpack WindowManager-Tests herunterzuladen. Die Tests befinden sich in der Fensterbibliothek im Modul window:window: window/window/src/androidTest/.

So führen Sie die Gerätetests für das window:window-Modul ü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-Repositories.
  4. Ändern Sie das Verzeichnis in framework/support.
  5. Führen Sie dazu diesen Befehl aus: ./gradlew window:window:connectedAndroidTest.
  6. Analysieren Sie die Ergebnisse.

So führen Sie die Tests über 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 Fensterbibliothek des Fenstermoduls 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 anhand der Ausgabe der Shell analysiert werden. Einige Tests werden übersprungen, wenn das Gerät bestimmte Annahmen nicht erfüllt. Die Ergebnisse werden an einem standardmäßigen Speicherort gespeichert. Analysten können ein Script schreiben, um die Analyse der Ergebnisse zu automatisieren.