Displayunterstützung

Im Folgenden finden Sie die Aktualisierungen, die an diesen Display-spezifischen Bereichen vorgenommen wurden:

Größe von Aktivitäten und Displays anpassen

Um darauf hinzuweisen, dass eine App den Mehrfenstermodus oder die Größenanpassung möglicherweise nicht unterstützt, Aktivitäten verwenden das Attribut resizeableActivity=false. Häufig Folgende Probleme treten bei Apps auf, wenn die Größe von Aktivitäten geändert wird:

  • Die Konfiguration einer Aktivität kann sich von der App oder einer anderen unterscheiden nicht-visuelle Komponente. Ein häufiger Fehler besteht darin, Displaymesswerte aus der App zu lesen. Kontext. Die zurückgegebenen Werte werden nicht an die Messwerte für den sichtbaren Bereich angepasst in in dem eine Aktivität angezeigt wird.
  • Eine Aktivität verarbeitet eventuell Größenanpassung und Abstürze nicht, zeigt eine verzerrte Benutzeroberfläche an oder verlieren den Status aufgrund eines Neustarts, ohne den Instanzstatus zu speichern.
  • Eine App könnte versuchen, absolute Eingabekoordinaten anstelle dieser relativ zur Fensterposition). Dies kann dazu führen, dass die Eingabe Mehrfenstermodus.

Unter Android 7 (und höher) kann eine App resizeableActivity=false, damit es immer im Vollbildmodus ausgeführt wird. In In diesem Fall verhindert die Plattform, dass Aktivitäten, deren Größe nicht angepasst werden kann, aufgeteilt werden. Bildschirm. Wenn der Nutzer versucht, über den Launcher eine Aktivität aufzurufen, deren Größe nicht angepasst werden kann Im Splitscreen-Modus beendet die Plattform den Splitscreen-Modus und startet die Aktivität mit nicht veränderbarer Größe im Vollbildmodus.

Apps, die dieses Attribut explizit auf false in der Manifest darf nicht im Mehrfenstermodus gestartet werden, es sei denn, die Kompatibilität angewendet wird:

  • Auf den Prozess, der alle Aktivitäten enthält, wird die gleiche Konfiguration angewendet und nicht aktivitätsbezogene Komponenten.
  • Die angewendete Konfiguration erfüllt die CDD-Anforderungen für App-Kompatibilität angezeigt wird.

Auch in Android 10 verhindert die Plattform nicht in der Größe veränderbar sind, aber nicht in den Splitscreen-Modus wechseln. vorübergehend skaliert, wenn die Aktivität eine feste Ausrichtung oder ein festes Seitenverhältnis deklariert hat Seitenverhältnis. Wenn nicht, wird die Größe der Aktivität so angepasst, dass sie den gesamten Bildschirm ausfüllt, wie in Android. 9 und niedriger.

Bei der Standardimplementierung wird die folgende Richtlinie angewendet:

Wenn eine Aktivität, die als nicht mit dem Mehrfenstermodus über die Verwendung des Attributs android:resizeableActivity eine der unten beschriebenen Bedingungen erfüllt, gilt Folgendes: Bildschirmkonfiguration geändert werden muss, werden die Aktivität und der Prozess mit dem ursprüngliche Konfiguration und der Nutzer erhält die Möglichkeit, App-Prozess, um die aktualisierte Bildschirmkonfiguration zu verwenden.

  • Ist eine feste Ausrichtung über die Anwendung von android:screenOrientation
  • Die App hat ein standardmäßiges maximales oder minimales Seitenverhältnis nach Ausrichtung auf API-Ebene oder deklariert das Seitenverhältnis explizit

Diese Abbildung zeigt eine Aktivität mit nicht anpassbarer Größe und einem angegebenen Seitenverhältnis. Beim Zusammenklappen des Geräts wird das Fenster verkleinert, damit es in den Bereich passt, während Beibehaltung des Seitenverhältnisses mit entsprechenden Letterbox-Balken. Außerdem wird ein wird dem Nutzer jedes Mal angezeigt, wenn der Anzeigebereich für wird die Aktivität geändert.

Beim Aufklappen werden Konfiguration, Größe und Seitenverhältnis des Geräts nicht ändern, aber die Option zum Neustarten der Aktivität wird angezeigt.

Wenn resizeableActivity nicht festgelegt (oder festgelegt auf true), unterstützt die App die Größenanpassung vollständig.

Implementierung

Eine Aktivität mit nicht anpassbarer Größe mit fester Ausrichtung oder festem Seitenverhältnis wird als Größenkompatibilitätsmodus (SCM) im Code. Die Bedingung wird definiert in ActivityRecord#shouldUseSizeCompatMode() Wenn eine SCM-Aktivität eingeführt wurde, ist die bildschirmbezogene Konfiguration (z. B. Größe oder Dichte) unveränderlich in der angeforderten Überschreibungskonfiguration, sodass die Aktivität nicht mehr abhängig ist, in der aktuellen Displaykonfiguration.

Wenn die SCM-Aktivität nicht den gesamten Bildschirm ausfüllen kann, ist sie oben ausgerichtet und horizontal zentriert. Die Aktivitätsgrenzen werden berechnet, indem AppWindowToken#calculateCompatBoundsTransformation()

Wenn bei einer SCM-Aktivität eine andere Bildschirmkonfiguration als die Container (z. B. wird die Größe der Anzeige angepasst oder die Aktivität wurde in einen anderen display), ist ActivityRecord#inSizeCompatMode() „wahr“ und SizeCompatModeActivityController (in der System-UI) empfängt den um die Schaltfläche für den Neustart des Prozesses anzuzeigen.

Displaygrößen und Seitenverhältnisse

Android 10 unterstützt neue Seitenverhältnisse von langen und schmalen Bildschirmen bis zu 1:1-Seitenverhältnissen. Apps können ApplicationInfo#maxAspectRatio und die ApplicationInfo#minAspectRatio des Bildschirms, die Sie bewältigen können.

App-Seitenverhältnisse unter Android 10

Abbildung 1: Beispiele für unter Android unterstützte App-Seitenverhältnisse 10

Geräteimplementierungen können sekundäre Displays mit Größen und niedrigere Auflösungen als für Android 9 und niedriger (mindestens 2, 5 Zoll Breite oder Höhe, mindestens 320 DP für smallestScreenWidth), aber nur Aktivitäten, die diese kleinen Displays unterstützen, .

Apps können die Aktivierung vornehmen, indem Sie eine unterstützte Mindestgröße angeben, die kleiner ist als der Zielanzeigegröße entspricht. Verwenden Sie die android:minHeight- und android:minWidth Aktivitätslayout-Attribute im AndroidManifest zurück.

Displayrichtlinien

Android 10 trennt bestimmte Displays und verschiebt sie der WindowManagerPolicy-Standardimplementierung in PhoneWindowManager auf Klassen pro Display, z. B.:

  • Anzeigestatus und Drehung
  • Tracking einiger Tasten und Bewegungsereignisse
  • System-UI und Dekorationsfenster

In Android 9 (und niedriger) wurde die PhoneWindowManager-Klasse Anzeigerichtlinien, Status und Einstellungen, Drehung, Rahmen für Dekorationsfenster und vieles mehr. Android 10 verlagert der DisplayPolicy-Klasse, mit Ausnahme des Rotations-Trackings, bei dem wurde nach DisplayRotation verschoben.

Anzeigefenster-Einstellungen

In Android 10 ist das konfigurierbare Display pro Display Die Einstellung für den Fenstermodus wurde um folgende Funktionen erweitert:

  • Standardmäßiger Fenstermodus
  • Overscan-Werte
  • Nutzerrotations- und Rotationsmodus
  • Erzwungene Größe, Dichte und Skalierungsmodus
  • Modus zum Entfernen von Inhalten (wenn die Anzeige entfernt wird)
  • Unterstützung für Systemdesigns und IME

Die Klasse DisplayWindowSettings enthält Einstellungen für diese Optionen. Sie werden dauerhaft auf dem Datenträger in der Partition /data gespeichert in display_settings.xml wird jedes Mal angezeigt, wenn eine Einstellung geändert wird. Für finden Sie unter DisplayWindowSettings.AtomicFileStorage und DisplayWindowSettings#writeSettings(). Gerätehersteller können Standardwerte für das Gerät in display_settings.xml angeben Konfiguration. Da die Datei jedoch in /data gespeichert ist, Möglicherweise ist eine zusätzliche Logik erforderlich, um die Datei wiederherzustellen, wenn sie durch einen Löschvorgang gelöscht wurde.

Standardmäßig verwendet Android 10 DisplayInfo#uniqueId als Kennung für eine Anzeige bei dauerhafter Speicherung die Einstellungen. uniqueId sollte für alle Bildschirme ausgefüllt sein. In ist es stabil für physische Bildschirme und Netzwerk-Displays. Es ist auch möglich, verwenden Sie den Port eines physischen Bildschirms als Kennung, die in DisplayWindowSettings#mIdentifier Bei jedem Schreibvorgang werden alle Einstellungen so geschrieben, dass der Schlüssel, der für einen Anzeigeeintrag in Speicherplatz. Weitere Informationen finden Sie unter Statische Display-IDs:

Einstellungen werden für bisherige Daten im Verzeichnis /data gespeichert Gründe. Ursprünglich wurden sie verwendet, um von Nutzern festgelegte Einstellungen wie Displaydrehung.

Statische Display-IDs

Android 9 (und niedriger) stellte keine stabilen Kennungen für Displays in den Framework. Wenn dem System ein Display hinzugefügt wurde, Display#mDisplayId oder DisplayInfo#displayId war die für diese Anzeige generiert werden, indem ein statischer Zähler erhöht wird. Wenn das System dasselbe Display hinzugefügt und entfernt hat, entstand eine andere ID.

Wenn auf einem Gerät während des Startvorgangs mehrere Bildschirme verfügbar waren, wurden diese möglicherweise werden je nach Zeitplan unterschiedliche Kennungen zugewiesen. Während Android 9 (und früher) DisplayInfo#uniqueId enthalten, enthält jedoch nicht genug zwischen Bildschirmen unterscheiden, da physische Displays als local:0 oder local:1 identifiziert, um dem integrierten und dem externen Bildschirm.

Android 10-Änderungen DisplayInfo#uniqueId um eine stabile ID hinzuzufügen und zwischen lokalen, Netzwerk- und virtuellen Displays.

Displaytyp Format
Lokal
local:<stable-id>
Netz
network:<mac-address>
Virtuell
virtual:<package-name-and-name>

Neben den Aktualisierungen von uniqueId DisplayInfo.address enthält DisplayAddress, einen Anzeige-ID, die auch nach einem Neustart stabil bleibt. In Android 10, DisplayAddress unterstützt physische und Netzwerk-Displays. DisplayAddress.Physical enthält eine stabile Anzeige-ID (wie in uniqueId) und kann mit DisplayAddress#fromPhysicalDisplayId()

Android 10 bietet auch eine bequeme Möglichkeit, Portinformationen (Physical#getPort()) Diese Methode kann in um Bildschirme statisch zu identifizieren. Zum Beispiel werden sie in DisplayWindowSettings. DisplayAddress.Network enthält die MAC-Adresse und kann mit DisplayAddress#fromMacAddress()

Diese Ergänzungen ermöglichen es Geräteherstellern, Displays in statischen Multi-Display-Anzeigen einrichten und unterschiedliche Systemeinstellungen und -funktionen konfigurieren mit statischen Displaykennungen, z. B. Ports für physische Displays. Diese sind verborgen und sollten nur in system_server

Bei einer HWC-Display-ID (die undurchsichtig und nicht immer stabil sein kann) gibt die (plattformspezifische) 8-Bit-Portnummer zurück, die eine physischer Connector für die Ausgabeanzeige sowie das EDID-Blob des Bildschirms. SurfaceFlinger extrahiert Hersteller- oder Modellinformationen aus der EDID, Generieren Sie die stabilen 64-Bit-Display-IDs, die dem Framework bereitgestellt werden. Wenn diese Methode nicht unterstützt wird oder Fehler auftreten, greift SurfaceFlinger auf den alten MD-Modus zurück, wobei DisplayInfo#address null ist und DisplayInfo#uniqueId ist wie oben beschrieben hartcodiert.

Führen Sie folgenden Befehl aus, um zu prüfen, ob dieses Feature unterstützt wird:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

Mehr als zwei Bildschirme verwenden

In Android 9 (und niedriger), SurfaceFlinger und DisplayManagerService wurde angenommen, dass höchstens zwei physische Displays mit hartcodierten IDs vorhanden sind 0 und 1.

Ab Android 10 könnte SurfaceFlinger eine Hardware Composer (HWC) API zum Generieren stabiler Anzeige-IDs für die Verwaltung von einer beliebigen Anzahl physischer Bildschirme. Weitere Informationen finden Sie unter Statische Display-IDs:

Das Framework kann das IBinder-Token für eine physische bis SurfaceControl#getPhysicalDisplayToken angezeigt werden, nachdem Sie die 64-Bit-Display-ID von SurfaceControl#getPhysicalDisplayIds oder von einem DisplayEventReceiver Hotplug-Ereignis.

In Android 10 (und niedriger) ist das primäre interne Display TYPE_INTERNAL und alle sekundären Displays sind als TYPE_EXTERNAL gekennzeichnet unabhängig vom Verbindungstyp. Daher werden zusätzliche interne Bildschirme wie extern behandelt. Als Behelfslösung kann gerätespezifischer Code Annahmen über DisplayAddress.Physical#getPort, wenn die HWC und die Portzuweisung bekannt sind Logik vorhersehbar ist.

Diese Einschränkung wird ab Android 11 aufgehoben.

  • In Android 11 wird während des Startvorgangs als Erstes der Bildschirm angezeigt, primären Displays. Der Verbindungstyp (intern oder extern) ist irrelevant. Das primäre Display kann jedoch nicht getrennt werden, In der Praxis muss es sich um eine interne Anzeige handeln. Beachte, dass einige faltbare Smartphones mehrere internen Displays.
  • Sekundäre Displays sind korrekt als Display.TYPE_INTERNAL kategorisiert oder Display.TYPE_EXTERNAL (früher Display.TYPE_BUILT_IN) und Display.TYPE_HDMI) je nach Verbindungstyp.

Implementierung

In Android 9 und niedriger werden Bildschirme durch 32-Bit-IDs, wobei 0 das interne Display, 1 das externe Display und [2, INT32_MAX] sind virtuelle HWC-Displays und -1 steht für eine ungültige Anzeige oder eine virtuelle Anzeige ohne HWC.

Ab Android 10 erhalten Displays stabil. und persistente IDs, die SurfaceFlinger und DisplayManagerService um mehr als zwei Displays zu erfassen und zuvor gesehene Displays zu erkennen. Wenn die HWC unterstützt IComposerClient.getDisplayIdentificationData und bietet Display-Anzeigen identifizierbar ist, parst SurfaceFlinger die EDID-Struktur und ordnet 64-Bit-Display-IDs für physische und virtuelle HWC-Displays. Die IDs werden mit einen Optionstyp, bei dem der Nullwert eine ungültige Anzeige oder eine virtuelle Nicht-HWC-Anzeige darstellt Display. Ohne HWC-Unterstützung greift SurfaceFlinger auf das alte Verhalten zurück, zwei physischen Displays.

Fokus pro Display

Um mehrere Eingabequellen zu unterstützen, die gleichzeitig auf einzelne Displays ausgerichtet sind kann Android 10 mehrere fokussierte Fenster, höchstens eines pro Bildschirm. Dies ist nur für spezielle wenn mehrere Nutzer mit demselben Gerät gleichzeitig interagieren. und unterschiedliche Eingabemethoden oder Geräte verwenden, z. B. Android Automobilindustrie

Es wird dringend empfohlen, diese Funktion nicht für normale Geräte, einschließlich Multiscreen-Geräten oder solche, die für Desktop-Geräte verwendet werden, User Experiences. Der Grund dafür sind in erster Linie Sicherheitsbedenken, durch die Nutzer unter Umständen welches Fenster den Eingabefokus hat.

Stellen Sie sich vor, Nutzende, die sichere Informationen in ein Texteingabefeld eingeben, zum Beispiel die Anmeldung in einer Banking-App oder die Eingabe von Text, der sensible Informationen. Eine schädliche App könnte ein virtuelles Off-Screen-Display mit die eine Aktivität ausführen soll, auch mit einem Texteingabefeld. Legitime und Böswillige Aktivitäten stehen im Fokus und beide zeigen eine aktive Eingabeanzeige (blinkender Cursor).

Da die Eingabe über die Tastatur (Hardware oder Software) jedoch nur die oberste Aktivität (die App, die zuletzt gestartet wurde), durch eine verborgene virtuelle Anzeige erstellen, könnte eine schädliche App Nutzereingaben erfassen, sogar wenn Sie eine Softwaretastatur auf dem primären Bildschirm des Geräts verwenden.

com.android.internal.R.bool.config_perDisplayFocusEnabled verwenden um den Fokus pro Display festzulegen.

Kompatibilität

Problem: Unter Android 9 und niedriger wurde höchstens ein Fenster im den Fokus jeweils hat.

Lösung:In dem seltenen Fall, dass zwei Fenster vom wenn derselbe Prozess fokussiert wäre, nur das Fenster fokussiert höher in der Z-Reihenfolge. Diese Einschränkung wird für Apps aufgehoben, die auf Android 10 entwickelt. Es wird erwartet, unterstützen mehrere Fenster, die gleichzeitig im Fokus sind.

Implementierung

WindowManagerService#mPerDisplayFocusEnabled steuert den dieser Funktion verfügbar sind. Im ActivityManager, ActivityDisplay#getFocusedStack() wird jetzt anstelle von global verwendet in einer Variablen fest. ActivityDisplay#getFocusedStack() bestimmt den Fokus auf der Z-Reihenfolge, anstatt den Wert im Cache zu speichern. Dadurch wird nur eine Quelle, WindowManager, die Z-Reihenfolge der Aktivitäten verfolgen muss.

ActivityStackSupervisor#getTopDisplayFocusedStack() nimmt eine Ein ähnlicher Ansatz, wenn der am stärksten fokussierte Stack im System ist, gekennzeichnet sein müssen. Die Stapel werden von oben nach unten durchlaufen, ersten zulässigen Stapel an.

InputDispatcher kann jetzt mehrere fokussierte Fenster haben (eine pro Display). Wenn ein Eingabeereignis displayspezifisch ist, wird es ausgelöst. zum fokussierten Fenster in der entsprechenden Anzeige. Andernfalls wird es gesendet, auf das fokussierte Fenster in der fokussierten Anzeige, d. h. die Anzeige, mit dem zuletzt interagiert hat.

Siehe InputDispatcher::mFocusedWindowHandlesByDisplay und InputDispatcher::setFocusedDisplay(). Fokussierte Apps werden ebenfalls aktualisiert separat im InputManagerService über NativeInputManager::setFocusedApplication()

In WindowManager werden fokussierte Fenster ebenfalls separat erfasst. Siehe DisplayContent#mCurrentFocus und DisplayContent#mFocusedApp und die entsprechenden Verwendungszwecke. Zugehöriger Schwerpunkt wurden Tracking- und Aktualisierungsmethoden WindowManagerService in DisplayContent.