WindowManager-Erweiterungen

Mit der Bibliothek Jetpack WindowManager können Anwendungsentwickler neue Geräteformfaktoren und Mehrfensterumgebungen unterstützen.

WindowManager Extensions (Extensions) ist ein Opt-in-Android-Plattformmodul, das eine Vielzahl von Jetpack WindowManager-Funktionen ermöglicht. 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.

Um Erweiterungen auf einem Gerät zu aktivieren, fügen Sie dem Produkt-Makefile für das Gerät 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 das Attribut persist.wm.extensions.enabled wird festgelegt. Wenn diese Pakete in das Makefile aufgenommen werden, werden auch Deklarationen in etc/permissions/ platziert, sodass sie für Anwendungsprozesse verfügbar sind. Normalerweise werden die Module zur Laufzeit im Rahmen des Anwendungsprozesses geladen und ausgeführt, wenn sie von der Jetpack WindowManager-Bibliothek verwendet werden. Dadurch ähnelt der Vorgang dem clientseitigen Framework-Code, wie in der folgenden Abbildung dargestellt:

Abbildung 1. WindowManager-Erweiterungen werden ähnlich wie Plattformcode in den Anwendungsprozess geladen.

Das Modul androidx.window.extensions ist das Modul „Extensions“, das aktuell aktiv entwickelt wird. Das Modul androidx.window.sidecar ist ein Legacy-Modul, das aus Gründen der Kompatibilität mit den frühesten Versionen von Jetpack WindowManager enthalten ist. Die Sidecar-Datei wird jedoch nicht mehr aktiv gewartet.

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 Bildschirm 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-Schnittstelle bereitstellen, wenn die Gerätehardware die entsprechenden Funktionen nicht unterstützt, es sei denn, die Funktion wird im Kompatibilitätsdefinitionsdokument (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 in einer nicht entwicklerseitigen androidx.window.extensions-Jetpack-Bibliothek veröffentlicht, sodass Jetpack WindowManager (androidx.window) bei der Kompilierung eine Verknüpfung herstellen 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 Extensions APIs sollen nicht direkt von Anwendungsentwicklern aufgerufen werden. 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 einer Anwendung vorab zu kompilieren. Verlassen Sie sich stattdessen auf das Laden der Laufzeit, um zu verhindern, dass eine Mischung aus vorkompilierten und von der 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 Anwendungsprozess und umschließt die untergeordneten Extensions APIs in übergeordneten Abstraktionen und fokussierteren Schnittstellen. Die WindowManager Jetpack APIs entsprechen den Standards der modernen Android-Anwendungsentwicklung und sollen eine bequeme Interoperabilität bieten, da sie gut in Codebasen integriert werden, die andere AndroidX-Bibliotheken verwenden.

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 WindowManager Extensions API-Ebene API-Version 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

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 übernimmt die Komplexität des Umgangs mit häufigen API-Level-Updates, einer schnellen API-Entwicklung und 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 Vorabveröffentlichungen von Erweiterungen kann nicht vor dem entsprechenden vierteljährlichen oder jährlichen Android-Plattformrelease aufrechterhalten werden, mit dem die Versionen abgeschlossen wurden. Den vollständigen Verlauf der Extensions APIs finden Sie im Release-Branch window:extensions:extensions API-Textdateien.

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. Anwendungen mit älteren WindowManager-Versionen können daher 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 Nicht-Bootclasspath-Ladeprogrammen im Cache gespeichert. Die Leistung wird also nicht beeinträchtigt, weil das Modul beim Start der App in den Arbeitsspeicher geladen wird. Die Verwendung einzelner Modulfunktionen kann einen geringen Einfluss auf die Leistungsmerkmale von Anwendungen haben, wenn zusätzliche IPC-Aufrufe zwischen dem Client und dem Server ausgeführt werden.

Module

Einbetten von Aktivitäten

Die Komponente Aktivitätseinbettung bietet eine Reihe von Funktionen, mit denen Anwendungen die Darstellung des Aktivitätsfensters innerhalb der Grenzen der übergeordneten Anwendung organisieren können. Dazu gehört die gleichzeitige Anzeige von zwei Aktivitäten in einem Mehrfensterlayout, was die Optimierung großer Bildschirme für Legacy-Anwendungen erleichtert.

Die Komponente zum Einbetten von Aktivitäten muss auf allen Geräten mit einem integrierten Display mit mindestens sw600 dp verfügbar sein. Auf Geräten, die externe Displayverbindungen unterstützen, muss auch die Aktivitätseinbettung aktiviert sein, da die App möglicherweise größer angezeigt wird, wenn externe Bildschirme während der Laufzeit verbunden sind.

Gerätekonfiguration

Abgesehen von der Aktivierung des Moduls „Erweiterungen“ müssen Sie lediglich das im Abschnitt Verteilung der Erweiterungsmodule beschriebene aktivieren. Erweiterungen sollten daher auf allen Geräten aktiviert werden, die den Mehrfenstermodus unterstützen. Erweiterungen werden in zukünftigen Android-Versionen wahrscheinlich für gängige Konfigurationen von Handheld-Geräten und Geräten für große Bildschirme erforderlich sein.

Informationen zum Fensterlayout

Die Komponente „Fensterlayoutinformationen“ ermittelt die Position und den Zustand des Scharniers an einem faltbaren Gerät, wenn das Scharnier durch ein Anwendungsfenster kreuzt. Informationen zum Fensterlayout ermöglichen es Apps, auf faltbare Smartphones zu reagieren und optimierte Layouts im Modus „Auf dem Tisch“ anzuzeigen. Weitere Informationen zur Verwendung finden Sie unter Ihre App für faltbare Geräte optimieren.

Faltbare Android-Geräte mit einem Scharnier, das separate oder fortlaufende Bereiche mit dem Displaybereich verbindet, müssen Apps über WindowLayoutComponent Informationen zum Scharnier zur Verfügung stellen.

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 Grenzen des Anwendungsfensters nicht mit den Scharniergrenzen überschneiden, darf das Scharnier DisplayFeature nicht gemeldet werden. Es ist auch zulässig, die Anzeigeelemente nicht zu melden, wenn ihre Position möglicherweise nicht zuverlässig gemeldet wird, z. B. wenn ein Anwendungsfenster vom Nutzer im Mehrfenstermodus oder im Kompatibilitäts-Letterbox-Modus frei verschoben werden kann.

Bei Faltelementen müssen die Statusaktualisierungen gemeldet werden, wenn sich die Position des Scharniers zwischen den stabilen Status ändert. In einem flachen Display muss die API standardmäßig FoldingFeature.State.FLAT melden. 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 Faltfunktion zu unterstützen, müssen OEMs Folgendes tun:

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

    Wenn die Standardimplementierungen von DeviceStateProvider oder DeviceStatePolicy für das Gerät nicht 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 com.android.internal.R.string.config_display_features-Stringressource 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 Bundesstaats-IDs werden unterstützt:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: Im Bundesstaat gibt es keine Faltfeatures, die gemeldet werden können. Es kann sich beispielsweise um den geschlossenen Zustand eines typischen faltbaren Geräts handeln, bei dem sich das Hauptdisplay an der Innenseite befindet.
    • COMMON_STATE_HALF_OPENED = 2: Die Faltfunktion ist zur Hälfte geöffnet.
    • COMMON_STATE_FLAT = 3: Die Faltfunktion ist flach. Das kann beispielsweise der geöffnete Zustand eines typischen faltbaren Geräts mit dem Hauptbildschirm auf der Innenseite sein.
    • COMMON_STATE_USE_BASE_STATE = 1000: In Android 14 ein Wert, der für emulierte Zustände 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.

Mit dem Rückdisplaymodus kann eine App die Benutzeroberfläche für die Kameravorschau auf dem Deckblatt eines faltbaren Geräts anzeigen. So kann die Hauptkamera des Geräts für Selfies und Videos verwendet werden. Geräte, die ein mit Android kompatibles Display haben (gemäß der Definition der Android-CDD in Bezug auf Attribute wie Größe, Dichte und verfügbare Navigationsoptionen), muss das Cover des Displays an die Rückseitenkameras anpassen und Zugriff auf den Rückdisplaymodus haben.

Unter Android 14 können Apps, die auf dem inneren Display eines faltbaren Geräts ausgeführt werden, im Modus mit zwei Displays zusätzliche Inhalte auf dem Coverdisplay anzeigen, das anderen Nutzern zugewandt ist. So kann beispielsweise die Kameravorschau auf dem Coverdisplay 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ä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.

  • Gib bei auffaltbaren Geräten, die zusammengeklappt werden können, die entsprechenden Status-IDs unter 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.
    • Gib die Adresse des hinteren Displays in com.android.internal.R.string.config_rearDisplayPhysicalAddress 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 Anwendungen zur Verfügung zu stellen.
  • Unter Android 14 auf Geräten, die den Dual Screen-Modus (gleichzeitige Nutzung) unterstützen:

    • Legen Sie com.android.internal.R.bool.config_supportsConcurrentInternalDisplays auf true fest.
    • Gib die Adresse des hinteren Displays in com.android.internal.R.config_deviceStateConcurrentRearDisplay an.
    • Geben Sie die Bundesstaatkennung in com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay 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 Anwendungen zur Verfügung zu stellen.

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 window:window-Modul: 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, bei dem Entwickleroptionen und 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 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 eine Konfiguration in Android Studio 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.