Vous trouverez ci-dessous les modifications apportées à ces zones spécifiques au Réseau Display:
- Redimensionnement des activités et de l'écran
- Tailles et formats d'affichage
- Règles d'affichage
- Paramètres de la fenêtre d'affichage
- Identifiants d'affichage statique
- Utiliser plus de deux écrans
- Mise au point par écran
Redimensionner les activités et les écrans
Pour indiquer qu'une appli peut ne pas prendre en charge le mode multifenêtre ou le redimensionnement,
les activités utilisent l'attribut resizeableActivity=false
. Commun
Voici quelques problèmes rencontrés par les applications lorsque les activités sont redimensionnées:
- Une activité peut avoir une configuration différente de celle de l'application ou d'une autre un composant non visuel. Une erreur courante consiste à lire les métriques d'affichage à partir de l'application. le contexte. Les valeurs renvoyées ne seront pas ajustées en fonction des métriques sur les zones visibles dans où une activité est affichée.
- Une activité peut ne pas gérer le redimensionnement et le plantage, afficher une UI déformée, ou perdre l'état suite à un redémarrage sans enregistrer l'état de l'instance.
- Une application peut tenter d'utiliser des coordonnées d'entrée absolues (au lieu de par rapport à la position de la fenêtre), ce qui peut interrompre l'entrée le mode multifenêtre.
Sous Android 7 (ou version ultérieure), vous pouvez définir une application
resizeableActivity=false
pour toujours s'exécuter en mode plein écran. Dans
dans ce cas, la plate-forme empêche les activités non redimensionnables d'être divisées
l'écran. Si l'utilisateur tente d'appeler une activité non redimensionnable à partir du lanceur d'applications
lorsqu'elle est déjà en mode Écran partagé, la plate-forme quitte le mode Écran partagé et
lance l'activité non redimensionnable en mode plein écran.
Les applications qui définissent explicitement cet attribut sur false
dans
le fichier manifeste ne doit pas être lancé en mode multifenêtre, à moins que le fichier
est appliqué:
- La même configuration est appliquée au processus, qui contient toutes les activités et hors activité.
- La configuration appliquée respecte les exigences du CDD pour la compatibilité avec les applications s'affiche.
Sous Android 10, la plate-forme empêche toujours les activités non redimensionnables de passer en mode Écran partagé, mais elles peuvent être temporairement mis à l'échelle si l'activité a déclaré une orientation ou un aspect fixe le ratio. Sinon, l'activité est redimensionnée pour remplir tout l'écran, comme dans Android. 9 et versions antérieures.
L'implémentation par défaut applique la règle suivante:
Lorsqu'une activité déclarée incompatible avec le mode multifenêtre via
utiliser l'attribut android:resizeableActivity
.
s'applique à l'une des conditions décrites ci-dessous, puis lorsque la requête
la configuration de l'écran doit changer, l'activité et le processus sont enregistrés
configuration d'origine et l'utilisateur reçoit une affordance pour le relancer
processus d'application pour utiliser la configuration d'écran mise à jour.
- Est à orientation fixe via l'application
android:screenOrientation
- L'application utilise un format maximal ou minimal par défaut en fonction du niveau d'API ciblé ou déclare explicitement le format
Cette figure montre une activité non redimensionnable dont le format a été déclaré. Lorsque vous pliez l'appareil, la fenêtre est réduite pour s'adapter à la zone tout en en conservant les proportions en utilisant le format letterbox approprié. De plus, un l'option "redémarrer l'activité" est proposée à l'utilisateur chaque fois que la zone d'affichage de l'activité est modifiée.
Lorsque vous dépliez l'appareil, la configuration, la taille et le format activité ne change pas, mais l’option pour redémarrer l’activité s’affiche.
Lorsque resizeableActivity
n'est pas défini (ou est défini sur
true
), l'application est entièrement compatible avec le redimensionnement.
Implémentation
Une activité non redimensionnable avec une orientation ou un format fixe est appelée
le mode de compatibilité de taille (SCM) dans le code. La condition est définie dans
ActivityRecord#shouldUseSizeCompatMode()
Lorsqu'une activité SCM est
la configuration liée à l'écran (comme la taille ou la densité) est fixe.
dans la configuration de remplacement demandée, de sorte que l'activité ne dépend plus
sur la configuration d'affichage actuelle.
Si l'activité SCM ne peut pas remplir tout l'écran, elle est alignée en haut et
centré horizontalement. Les limites d'activité sont calculées
AppWindowToken#calculateCompatBoundsTransformation()
Lorsqu'une activité SCM utilise une configuration d'écran différente de celle
conteneur (par exemple, l'écran est redimensionné ou l'activité est déplacée vers une autre
display), ActivityRecord#inSizeCompatMode()
est "true" et
SizeCompatModeActivityController
(dans l'UI du système) reçoit les
rappel pour afficher le bouton de redémarrage du processus.
Tailles et formats d'affichage
Android 10 est compatible avec de nouveaux formats
des rapports élevés d'écrans longs et
fins à des rapports 1:1. Les applications peuvent définir
ApplicationInfo#maxAspectRatio
et le ApplicationInfo#minAspectRatio
de l'écran
à gérer.
Figure 1 : Exemples de formats d'application compatibles avec Android 10.
Les implémentations d'appareils peuvent avoir
des écrans secondaires avec des tailles et
inférieures à celles requises par Android 9 ou inférieures (minimum 2, 5
en largeur ou en hauteur, minimale de 320 DP pour smallestScreenWidth
),
mais seules les activités
compatibles avec ces petits écrans peuvent être placées
ici.
Les applications peuvent l'activer en déclarant une taille minimale prise en charge inférieure à
ou égal à la taille d'affichage cible. Utiliser android:minHeight
et
Attributs de mise en page de l'activité android:minWidth
dans
AndroidManifest.
Règles d'affichage
Android 10 sépare et déplace certains écrans
de l'implémentation par défaut de WindowManagerPolicy
dans
PhoneWindowManager
à des classes par écran, telles que:
- État et rotation de l'écran
- Quelques touches et suivi des événements de mouvement
- UI du système et fenêtres de décoration
Sous Android 9 (et versions antérieures), la classe PhoneWindowManager
gérait
règles d'affichage, état et paramètres, rotation, cadre de la fenêtre de décoration
le suivi, etc. Android 10 migre la majeure partie
la classe DisplayPolicy
, à l'exception du suivi de la rotation, qui
a été déplacé vers DisplayRotation
.
Paramètres de la fenêtre d'affichage
Sous Android 10, le paramètre configurable par écran Le paramètre de fenêtrage a été étendu pour inclure:
- Mode de fenêtrage d'affichage par défaut
- Valeurs de surbalayage
- Rotation et mode de rotation des utilisateurs
- Taille, densité et mode de scaling imposés
- Mode de suppression de contenu (lorsque l'écran est retiré)
- Prise en charge des décorations système et IME
La classe DisplayWindowSettings
contient des paramètres pour ces
options. Ils sont conservés sur le disque dans la partition /data
dans
display_settings.xml
chaque fois qu'un paramètre est modifié. Pour
détails, consultez DisplayWindowSettings.AtomicFileStorage
et
DisplayWindowSettings#writeSettings()
Les fabricants d'appareils peuvent
fournissent des valeurs par défaut dans display_settings.xml
pour leur appareil
configuration. Toutefois, comme le fichier est stocké dans /data
,
une logique supplémentaire peut être nécessaire pour restaurer le fichier s'il est effacé par un effacement de données.
Par défaut, Android 10 utilise
DisplayInfo#uniqueId
en tant qu'identifiant d'un écran lorsqu'il est persistant
les paramètres. uniqueId
doit être renseigné pour tous les écrans. Dans
De plus, il est stable pour les écrans
physiques et réseau. Il est également possible de
utiliser le port d'un écran physique comme identifiant, qui peut être défini dans
DisplayWindowSettings#mIdentifier
À chaque écriture, tous les paramètres
sont écrites afin de pouvoir mettre à jour sans risque la clé utilisée pour une entrée d'affichage dans
stockage. Pour en savoir plus, consultez
Identifiants d'affichage statique.
Les paramètres sont conservés dans le répertoire /data
pour l'historique
raisons. À l'origine, ils étaient utilisés pour conserver les paramètres définis par l'utilisateur, tels que
la rotation de l'écran.
Identifiants d'affichage statique
Android 9 (et versions antérieures) ne fournissait pas d'identifiants stables pour les écrans dans
d'infrastructure. Lorsqu'un écran a été
ajouté au système,
Display#mDisplayId
ou DisplayInfo#displayId
était
généré pour cet affichage en incrémentant un compteur statique. Si le système
ajouté et supprimé le même affichage, un ID différent est généré.
Si plusieurs écrans sont disponibles au démarrage sur un appareil, il est possible qu'ils soient
des identifiants différents, selon le moment. Bien qu'Android 9 (et
précédemment) incluait DisplayInfo#uniqueId
, qui n'en contenait pas assez
pour différencier les écrans, car les supports physiques étaient
identifié comme local:0
ou local:1
, pour représenter
l'écran intégré et l'écran externe.
Modifications apportées à Android 10 DisplayInfo#uniqueId
d'ajouter un identifiant stable et de différencier
écrans virtuels.
Type d'affichage | Format |
---|---|
Local | local:<stable-id> |
Réseau | network:<mac-address> |
Virtuel | virtual:<package-name-and-name> |
En plus des modifications apportées à uniqueId
,
DisplayInfo.address
contient DisplayAddress
, un
un identifiant d'affichage stable entre les redémarrages. Sur Android
10, DisplayAddress
prend en charge les
et les affichages du réseau. DisplayAddress.Physical
contient un élément stable
ID display (identique à uniqueId
) et peuvent être créés avec
DisplayAddress#fromPhysicalDisplayId()
Android 10 constitue également une méthode pratique
informations sur le port (Physical#getPort()
). Cette méthode peut être utilisée
le framework d'identifier les écrans de manière statique. Par exemple, il est utilisé dans
DisplayWindowSettings
). DisplayAddress.Network
contient l'adresse MAC et peut être créé avec
DisplayAddress#fromMacAddress()
Ces ajouts permettent aux fabricants d'appareils d'identifier les écrans dans des images
configurations multi-écrans, et pour configurer différents paramètres et fonctionnalités système
à l'aide d'identifiants d'affichage statiques, tels que les ports d'écrans physiques. Ces
méthodes sont masquées et ne sont destinées qu'à être utilisées
system_server
Avec un identifiant d'affichage HWC (qui peut être opaque et pas toujours stable), cela
renvoie le numéro de port 8 bits (spécifique à la plate-forme) qui identifie un
connecteur physique pour la sortie d'affichage, ainsi que le blob EDID de l'écran.
SurfaceFlinger extrait les informations sur le fabricant ou le modèle de l'EDID pour
générer les ID d'affichage 64 bits stables exposés au framework. Si cette méthode
n'est pas pris en charge ou des erreurs, SurfaceFlinger revient à l'ancien mode MD,
où DisplayInfo#address
est nul et
DisplayInfo#uniqueId
est codé en dur, comme décrit ci-dessus.
Pour vérifier que cette fonctionnalité est compatible, exécutez la commande suivante:
$ 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"
Utiliser plus de deux écrans
Sous Android 9 (et versions antérieures), SurfaceFlinger et DisplayManagerService
a supposé l'existence de deux écrans physiques au maximum avec des ID 0 codés en dur
et 1.
À partir d'Android 10, SurfaceFlinger pouvait exploiter L'API Hardware Composer (HWC) pour générer des ID d'affichage stables, ce qui lui permet de gérer un nombre arbitraire d'écrans physiques. Pour en savoir plus, consultez Identifiants d'affichage statique.
Le framework peut rechercher le jeton IBinder
pour un jeton physique
afficher via SurfaceControl#getPhysicalDisplayToken
après avoir obtenu
l'ID d'affichage 64 bits de SurfaceControl#getPhysicalDisplayIds
ou
à partir d'un événement de connexion à chaud DisplayEventReceiver
.
Sous Android 10 (et versions antérieures), l'écran interne principal est
TYPE_INTERNAL
et tous les écrans secondaires sont signalés comme TYPE_EXTERNAL
quel que soit le type de connexion. Par conséquent, tout écran interne supplémentaire est considéré comme externe.
Pour contourner ce problème, le code spécifique à l'appareil peut émettre des hypothèses sur
DisplayAddress.Physical#getPort
si le HWC est connu et l'allocation de ports
est prévisible.
Cette limitation a été supprimée dans Android 11 (et versions ultérieures).
- Dans Android 11, le premier écran signalé au démarrage est l'écran principal. Le type de connexion (interne ou externe) n'a pas d'importance. Cependant, il reste vrai que l'écran principal ne peut pas être déconnecté et suit ce qui suit : il doit s'agir d'un affichage interne. Notez que certains téléphones pliables possèdent plusieurs écrans internes.
- Les écrans secondaires sont classés correctement dans la catégorie
Display.TYPE_INTERNAL
ouDisplay.TYPE_EXTERNAL
(anciennementDisplay.TYPE_BUILT_IN
etDisplay.TYPE_HDMI
, respectivement) en fonction de leur type de connexion.
Implémentation
Sous Android 9 et versions antérieures, les écrans sont identifiés par des ID 32 bits,
où 0 correspond à l'écran interne, 1 à l'écran externe, [2, INT32_MAX]
sont des écrans virtuels HWC, et "-1" représente un écran non valide ou un écran virtuel non HWC.
À partir d'Android 10, les écrans sont stables
et persistants, ce qui permet à SurfaceFlinger et DisplayManagerService
pour suivre plus de deux écrans et reconnaître ceux déjà vus. Si le matériel
prend en charge IComposerClient.getDisplayIdentificationData
et fournit des ressources d'affichage
d'identification, SurfaceFlinger analyse la structure de l'EDID et attribue des valeurs
ID d'affichage 64 bits pour les écrans virtuels physiques et physiques Les identifiants sont exprimés à l'aide de
Un type d'option, où la valeur nulle représente un affichage non valide ou une VM
l'écran. Sans compatibilité HWC, SurfaceFlinger revient à l'ancien comportement avec
deux écrans physiques.
Sélection par écran
Pour prendre en charge plusieurs sources d'entrée qui ciblent à la fois des écrans individuels temps, Android 10 peut être configuré pour prendre en charge plusieurs pour chacune des fenêtres sélectionnées, au maximum une par écran. Ceci est destiné uniquement aux cas d'utilisation Types d'appareils lorsque plusieurs utilisateurs interagissent avec le même appareil à la fois et utilisent différents modes de saisie ou périphériques, comme Android Automobile.
Il est fortement recommandé de ne pas activer cette fonctionnalité pour les appareils standards, y compris les appareils multi-écrans ou les appareils de bureau expériences. Cela est principalement dû à un problème de sécurité susceptible à se demander quelle fenêtre est sélectionnée en entrée.
Imaginez que l’utilisateur qui saisit des informations sécurisées dans un champ de saisie de texte, en se connectant à une application bancaire ou en saisissant du texte contenant des informations des informations. Une application malveillante pourrait créer un affichage virtuel hors écran avec exécuter une activité, également avec un champ de saisie de texte. Légalité et les activités malveillantes sont ciblées et affichent toutes deux un indicateur de saisie active (curseur clignotant).
Cependant, étant donné que la saisie à partir d'un clavier (matériel ou logiciel) est saisie dans l'activité la plus élevée uniquement (l'application la plus récemment lancée), par créant un affichage virtuel caché, une application malveillante pourrait capturer l'entrée utilisateur, lorsque vous utilisez un clavier virtuel sur l'écran principal de l'appareil.
Utiliser com.android.internal.R.bool.config_perDisplayFocusEnabled
pour définir la sélection par écran.
Compatibilité
Problème:sur Android 9 ou version antérieure, une seule fenêtre au maximum dans la au système actif à un moment donné.
Solution:dans les rares cas où deux fenêtres du même processus serait ciblé, le système ne sélectionne que la fenêtre qui est plus haut dans l'ordre Z. Cette restriction est supprimée pour les applications qui ciblent Android 10, on s'attend à ce qu'ils puissent prendre en charge que plusieurs fenêtres soient sélectionnées simultanément.
Implémentation
WindowManagerService#mPerDisplayFocusEnabled
contrôle les
la disponibilité de cette fonctionnalité. Dans ActivityManager
,
ActivityDisplay#getFocusedStack()
est désormais utilisé à la place de l'attribut global
le suivi dans une variable. ActivityDisplay#getFocusedStack()
détermine l'objectif en fonction de l'ordre de plan au lieu de mettre en cache la valeur. Ainsi,
une seule source, WindowManager, doit suivre l'ordre de plan des activités.
ActivityStackSupervisor#getTopDisplayFocusedStack()
prend un
une approche similaire pour les cas où la pile la plus ciblée du système
doit être identifié. Les piles sont balayées de haut en bas, à la recherche de
la première pile éligible.
InputDispatcher
peut désormais avoir plusieurs fenêtres sélectionnées
(un par écran). Si un événement d'entrée est spécifique à l'affichage, il est envoyé.
à la fenêtre sélectionnée de l'écran correspondant. Sinon, il est envoyé
à la fenêtre sélectionnée dans l'écran sélectionné, qui correspond à l'écran sur lequel l'utilisateur
avez interagi le plus récemment.
Voir InputDispatcher::mFocusedWindowHandlesByDisplay
et
InputDispatcher::setFocusedDisplay()
Les applis sélectionnées sont aussi mises à jour
séparément dans InputManagerService,
NativeInputManager::setFocusedApplication()
Dans WindowManager
, les fenêtres sélectionnées font également l'objet d'un suivi séparé.
Voir DisplayContent#mCurrentFocus
et
DisplayContent#mFocusedApp
et leurs utilisations respectives. Thème connexe
les méthodes de suivi et de mise à jour
De WindowManagerService
à DisplayContent
.