Gli aggiornamenti apportati a queste aree specifiche della visualizzazione sono riportati di seguito:
- Ridimensionare attività e display
- Dimensioni e proporzioni del display
- Norme della Rete Display
- Impostazioni della finestra del display
- Identificatori di visualizzazione statici
- Utilizzare più di due display
- Obiettivo per display
Ridimensionare attività e display
Per indicare che un'app potrebbe non supportare la modalità multi-finestra o il ridimensionamento,
attività utilizzano l'attributo resizeableActivity=false
. Comuni
I problemi riscontrati dalle app quando le attività vengono ridimensionate includono:
- Un'attività può avere una configurazione diversa da quella dell'app o di un'altra non visivo. Un errore comune è leggere le metriche del display dall'app contesto. I valori restituiti non saranno regolati in base alle metriche dell'area visibile in in cui viene visualizzata un'attività.
- Un'attività potrebbe non gestire il ridimensionamento e l'arresto anomalo, visualizzare un'interfaccia utente distorta o perdere lo stato a causa del riavvio senza salvare lo stato dell'istanza.
- Un'app può tentare di utilizzare coordinate di input assoluti (anziché coordinate) rispetto alla posizione della finestra), il che può interrompere l'input multi-finestra.
In Android 7 (e versioni successive), è possibile impostare un'app
resizeableActivity=false
per l'esecuzione in modalità a schermo intero. Nella
In questo caso, la piattaforma impedisce che le attività non ridimensionabili vengano suddivise
schermo. Se l'utente cerca di richiamare un'attività non ridimensionabile da Avvio app
mentre è già in modalità schermo diviso, la piattaforma esce dalla modalità schermo diviso
avvia l'attività non ridimensionabile in modalità a schermo intero.
App che impostano esplicitamente questo attributo su false
in:
il file manifest non deve essere avviato in modalità multi-finestra, a meno che la compatibilità
:
- La stessa configurazione viene applicata al processo, che contiene tutte le attività e non attività.
- La configurazione applicata soddisfa i requisiti CDD per la compatibilità con le app vengono visualizzati i video.
In Android 10, la piattaforma continua a impedire non ridimensionabili passino alla modalità schermo diviso, ma possono scalata temporaneamente se l'attività ha dichiarato un orientamento o un aspetto fisso rapporto. In caso contrario, l'attività si ridimensiona per occupare l'intero schermo come in Android. 9 e inferiori.
L'implementazione predefinita applica le seguenti norme:
Quando un'attività dichiarata incompatibile con la modalità multi-finestra tramite
l'utilizzo dell'attributo android:resizeableActivity
e quando
soddisfa una delle condizioni descritte di seguito, poi quando l'impostazione
configurazione dello schermo deve cambiare, l'attività e il processo vengono salvati
configurazione originale e all'utente viene fornita l'autorizzazione per eseguire il riavvio
il processo dell'app per utilizzare la configurazione dello schermo aggiornata.
- È un orientamento fisso tramite l'applicazione
android:screenOrientation
- L'app ha proporzioni minime o massime predefinite per il livello API target o dichiara esplicitamente le proporzioni
Questa figura mostra un'attività non ridimensionabile con proporzioni dichiarate. Quando pieghi il dispositivo, la finestra viene ridimensionata per adattarsi all'area, mentre mantenendo le proporzioni utilizzando il letterbox appropriato. Inoltre, l'opzione di riavvio attività viene fornita all'utente ogni volta che l'area di visualizzazione l'attività viene modificata.
Quando apri il dispositivo, la configurazione, le dimensioni e le proporzioni l'attività non cambia, ma viene visualizzata l'opzione per riavviarla.
Se il criterio resizeableActivity
non è impostato (o è impostato su
true
), l'app supporta completamente il ridimensionamento.
Implementazione
Viene definita un'attività non ridimensionabile con orientamento o formato fisso
modalità di compatibilità delle dimensioni (SCM) nel codice. La condizione è definita in
ActivityRecord#shouldUseSizeCompatMode()
. Quando un'attività SCM viene
viene avviato, la configurazione relativa allo schermo (come dimensioni o densità) è fissa
nella configurazione di override richiesta, quindi l'attività non dipende più
con l'attuale configurazione del display.
Se l'attività SCM non può occupare l'intero schermo, è allineata in alto e
centrato orizzontalmente. I limiti di attività vengono calcolati
AppWindowToken#calculateCompatBoundsTransformation()
.
Quando un'attività SCM utilizza una configurazione dello schermo diversa da quella
(ad esempio, la visualizzazione viene ridimensionata o l'attività viene spostata in un altro
display), ActivityRecord#inSizeCompatMode()
è true e
SizeCompatModeActivityController
(nell'UI di sistema) riceve
per mostrare il pulsante di riavvio del processo.
Dimensioni e proporzioni del display
Android 10 supporta nuove proporzioni
che spaziano da schermi lunghi e sottili a proporzioni 1:1. Le app possono definire
ApplicationInfo#maxAspectRatio
e ApplicationInfo#minAspectRatio
dello schermo che
gestibili.
Figura 1. Esempi di proporzioni delle app supportate in Android 10
Le implementazioni dei dispositivi possono avere display secondari con dimensioni e
Risoluzioni inferiori a quelle richieste da Android 9 e inferiori (minimo 2, 5
pollici di larghezza o altezza, minimo 320 DP per smallestScreenWidth
),
ma puoi inserire solo le attività che attivano il supporto di questi piccoli display
là.
Le app possono essere attivate dichiarando una dimensione minima supportata inferiore a
o uguale alle dimensioni di visualizzazione target. Utilizza android:minHeight
e
Attributi di layout delle attività android:minWidth
in
AndroidManifest.
Norme per la visualizzazione
Android 10 separa e sposta alcuni display
criteri dell'implementazione predefinita di WindowManagerPolicy
in
PhoneWindowManager
alle classi per visualizzazione, ad esempio:
- Stato e rotazione del display
- Alcuni tasti e rilevamento degli eventi di movimento
- UI di sistema e finestre decorative
In Android 9 (e versioni precedenti), la classe PhoneWindowManager
ha gestito
criteri di visualizzazione, stato e impostazioni, rotazione, cornice della finestra decorativa
monitoraggio e altro ancora. Android 10 sposta la maggior parte di questo
la classe DisplayPolicy
, ad eccezione del monitoraggio della rotazione, che ha
è stato spostato in DisplayRotation
.
Impostazioni della finestra di visualizzazione
In Android 10, il livello configurabile per display l'impostazione windowing è stata ampliata per includere:
- Modalità windowing predefinita
- Valori overscan
- Modalità di rotazione e rotazione utenti
- Modalità di scalabilità, densità e dimensioni forzate
- Modalità di rimozione dei contenuti (quando viene rimossa la visualizzazione)
- Supporto per le decorazioni del sistema e l'IME
Il corso DisplayWindowSettings
contiene impostazioni per queste
le opzioni di CPU e memoria disponibili. Sono resi persistenti su disco nella partizione /data
in
display_settings.xml
ogni volta che un'impostazione viene modificata. Per
dettagli, vedi DisplayWindowSettings.AtomicFileStorage
e
DisplayWindowSettings#writeSettings()
. I produttori di dispositivi possono
fornire valori predefiniti in display_settings.xml
per il proprio dispositivo
configurazione. Tuttavia, poiché il file è archiviato in /data
,
potrebbe essere necessaria una logica aggiuntiva per ripristinare il file se cancellato con la cancellazione dei dati.
Per impostazione predefinita, Android 10 utilizza
DisplayInfo#uniqueId
come identificatore di un display se persistente
le impostazioni. Il campo uniqueId
deve essere compilato per tutte le visualizzazioni. Nella
inoltre, è stabile per i display fisici e di rete. È inoltre possibile
utilizzare la porta di un display fisico come identificatore, che può essere impostato
DisplayWindowSettings#mIdentifier
. A ogni scrittura, tutte le impostazioni
vengono scritti, in modo che sia sicuro aggiornare la chiave utilizzata per una voce di visualizzazione in
archiviazione. Per maggiori dettagli, vedi
Identificatori di visualizzazione statici.
Le impostazioni sono persistenti nella directory /data
per la cronologia
motivi. In origine, venivano utilizzati per mantenere le impostazioni configurate dall'utente, come
la rotazione del display.
Identificatori di visualizzazione statici
Android 9 (e versioni precedenti) non forniva identificatori stabili per i display nel
il modello di machine learning. Quando un display è stato aggiunto al sistema,
Display#mDisplayId
o DisplayInfo#displayId
era
generate per quella visualizzazione incrementando un contatore statico. Se il sistema
aggiunto e rimosso lo stesso display, è stato generato un ID diverso.
Se su un dispositivo erano disponibili più display dall'avvio, questi potrebbero essere
assegnati identificatori diversi, a seconda delle tempistiche. Mentre Android 9 (e
precedente) ha incluso DisplayInfo#uniqueId
, non conteneva abbastanza
informazioni per distinguere tra i display perché i display fisici erano
identificato come local:0
o local:1
, per rappresentare
il display esterno e integrato.
Modifiche ad Android 10 DisplayInfo#uniqueId
per aggiungere un identificatore stabile e distinguere tra
display virtuali.
Tipo di display | Formato |
---|---|
Locale | local:<stable-id> |
Rete | network:<mac-address> |
Virtuale | virtual:<package-name-and-name> |
Oltre agli aggiornamenti di uniqueId
,
DisplayInfo.address
contiene DisplayAddress
, un
che sia stabile tra i riavvii. Su Android
10, DisplayAddress
supporta l'accesso fisico
e display di rete. DisplayAddress.Physical
contiene uno stabile
ID display (come in uniqueId
) e può essere creato con
DisplayAddress#fromPhysicalDisplayId()
.
Android 10 offre anche un pratico metodo per ottenere
informazioni sulla porta (Physical#getPort()
). Questo metodo può essere utilizzato
il framework per identificare in modo statico i display. Ad esempio, è utilizzato in
DisplayWindowSettings
). DisplayAddress.Network
contiene l'indirizzo MAC e può essere creato con
DisplayAddress#fromMacAddress()
.
Queste aggiunte consentono ai produttori di dispositivi di identificare i display nelle immagini statiche
configurazioni multi-display e di configurare diverse impostazioni e funzionalità di sistema
tramite identificatori di display statici, ad esempio le porte per i display fisici. Questi
sono nascosti e sono destinati a essere utilizzati solo all'interno
system_server
.
Dato un ID visualizzazione HWC (che può essere opaco e non sempre stabile), questo
restituisce il numero di porta a 8 bit (specifico della piattaforma) che identifica
connettore fisico per l'output del display, nonché il blob EDID del display.
SurfaceFlinger estrae le informazioni sul produttore o sul modello dall'EDID per
generano ID display stabili a 64 bit esposti al framework. Se questo metodo
non è supportato o si verificano errori, SurfaceFlinger utilizza la modalità MD legacy,
dove DisplayInfo#address
è nullo
Il parametro DisplayInfo#uniqueId
è hardcoded, come descritto sopra.
Per verificare che questa funzionalità sia supportata, esegui:
$ 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"
Usa più di due display
In Android 9 (e versioni precedenti), SurfaceFlinger e DisplayManagerService
presume l'esistenza di al massimo due display fisici con ID hard-coded 0
e 1.
A partire da Android 10, SurfaceFlinger potrebbe sfruttare una API Hardware Composer (HWC) per generare ID display stabili, al fine di gestire un numero arbitrario di display fisici. Per saperne di più, vedi Identificatori di visualizzazione statici.
Il framework può cercare il token IBinder
per trovare un token fisico
tramite SurfaceControl#getPhysicalDisplayToken
dopo aver ottenuto
l'ID display a 64 bit di SurfaceControl#getPhysicalDisplayIds
oppure
da un evento hotplug DisplayEventReceiver
.
In Android 10 (e versioni precedenti), il display interno principale è
TYPE_INTERNAL
e tutti i display secondari sono contrassegnati come TYPE_EXTERNAL
a prescindere dal tipo di connessione. Di conseguenza, i display interni aggiuntivi vengono considerati esterni.
Come soluzione alternativa, il codice specifico del dispositivo può fare ipotesi
DisplayAddress.Physical#getPort
se l'HWC è noto e l'allocazione delle porte
della logica è prevedibile.
Questa limitazione è stata rimossa in Android 11 e versioni successive.
- In Android 11, il primo display segnalato durante l'avvio è display principale. Il tipo di connessione (interna o esterna) non è pertinente. Tuttavia, rimane vero che il display principale non può essere disconnesso e segue questo deve essere una visualizzazione interna. Alcuni smartphone pieghevoli hanno diverse display interni.
- I display secondari sono classificati correttamente come
Display.TYPE_INTERNAL
oDisplay.TYPE_EXTERNAL
(precedentemente noto comeDisplay.TYPE_BUILT_IN
eDisplay.TYPE_HDMI
) a seconda del tipo di connessione.
Implementazione
In Android 9 e versioni precedenti, i display sono identificati da ID a 32 bit.
dove 0 è il display interno, 1 è il display esterno, [2, INT32_MAX]
sono display virtuali HWC e -1 rappresenta un display non valido o non HWC.
A partire da Android 10, i display hanno una stabilità
e ID permanenti, che consentono a SurfaceFlinger e DisplayManagerService
per monitorare più di due display e riconoscere quelli già visualizzati. Se l'HWC
supporta IComposerClient.getDisplayIdentificationData
e fornisce display
di identificazione dei dati, SurfaceFlinger analizza la struttura EDID e alloca
ID di visualizzazione a 64 bit per display fisici e virtuali HWC. Gli ID vengono espressi utilizzando
un tipo di opzione, dove il valore nullo rappresenta una visualizzazione non valida o un'istanza virtuale non HWC
display. Senza il supporto di HWC, SurfaceFlinger utilizza il comportamento precedente
due display fisici.
Focus per display
Per supportare diverse origini di input che hanno come target singoli display contemporaneamente volta, Android 10 può essere configurato per supportare finestre attive, al massimo una per display. È destinato esclusivamente a servizi speciali tipi di dispositivi quando più utenti interagiscono con lo stesso dispositivo alla stessa ora e utilizzare diversi metodi di immissione o dispositivi, ad esempio Android Auto e motori.
Ti consigliamo vivamente di non abilitare questa funzionalità per I dispositivi normali, compresi i dispositivi multischermo o quelli utilizzati per computer ed esperienze variegate. Ciò è dovuto principalmente a un problema di sicurezza che potrebbe causare per chiederti quale finestra ha lo stato attivo dell'input.
Immagina un utente che inserisce informazioni sicure in un campo di immissione di testo, magari accedendo a un'app di online banking o inserendo del testo che contiene dati sensibili informazioni. Un'app dannosa potrebbe creare un display virtuale fuori schermo con che eseguire un'attività, anche con un campo di immissione testo. Legittima e le attività dannose sono focalizzate ed entrambe mostrano un indicatore di input attivo (cursore lampeggiante).
Tuttavia, poiché l'input da una tastiera (hardware o software) viene inserito in solo l'attività principale (l'app lanciata più di recente), creando un display virtuale nascosto, un'app dannosa potrebbe afferrare l'input dell'utente, quando utilizzi una tastiera software sul display principale del dispositivo.
Usa com.android.internal.R.bool.config_perDisplayFocusEnabled
da impostare per ogni visualizzazione.
Compatibilità
Problema: in Android 9 e versioni precedenti, al massimo una finestra nell'area di un sistema operativo alla volta.
Soluzione: nel raro caso in cui due finestre dalla finestra lo stesso processo sarebbe focalizzato, il sistema mette in evidenza solo la finestra più alto nell'ordine Z. Questa limitazione viene rimossa per le app che hanno come target Android 10, a quel punto si prevede che possano supporta più finestre attive contemporaneamente.
Implementazione
WindowManagerService#mPerDisplayFocusEnabled
controlla
la disponibilità di questa funzione. A ActivityManager
,
Ora è in uso ActivityDisplay#getFocusedStack()
al posto di Global
il monitoraggio in una variabile. ActivityDisplay#getFocusedStack()
determina l'attenzione in base all'ordine Z invece di memorizzare il valore nella cache. Questo avviene di modo
solo un'origine, WindowManager, deve tenere traccia dell'ordine Z delle attività.
ActivityStackSupervisor#getTopDisplayFocusedStack()
richiede un
un approccio simile nei casi in cui lo stack più focalizzato nel sistema
devono essere identificati. Le farfalle vengono attraversate dall'alto verso il basso, alla ricerca
il primo stack idoneo.
Ora InputDispatcher
può avere più finestre con stato attivo
(uno per display). Se un evento di input è specifico per la visualizzazione, viene inviato
alla finestra con lo stato attivo nel display corrispondente. Altrimenti, viene spedito
alla finestra con lo stato attivo, che è il display selezionato dall'utente
con cui ha interagito più di recente.
Vedi InputDispatcher::mFocusedWindowHandlesByDisplay
e
InputDispatcher::setFocusedDisplay()
. Vengono aggiornate anche le app mirate
separatamente in InputManagerService tramite
NativeInputManager::setFocusedApplication()
.
In WindowManager
, le finestre con lo stato attivo vengono monitorate separatamente.
Vedi DisplayContent#mCurrentFocus
e
DisplayContent#mFocusedApp
e i rispettivi utilizzi. Argomento correlato
i metodi di monitoraggio e aggiornamento sono stati spostati da
Da WindowManagerService
a DisplayContent
.