Di seguito sono riportati gli aggiornamenti apportati a queste aree specifiche per i display:
Decorazioni di sistema
Android 10 aggiunge il supporto per la configurazione dei display secondari in modo da mostrare determinate decorazioni di sistema, come sfondo, barra di navigazione e Avvio app. Per impostazione predefinita, il display principale mostra tutte le decorazioni di sistema, mentre quelle facoltative vengono mostrate sui display secondari. Il supporto di un editor di metodi di inserimento (IME) può essere impostato separatamente da altre decorazioni di sistema.
Utilizza DisplayWindowSettings#setShouldShowSystemDecorsLocked()
per aggiungere il supporto per le decorazioni di sistema su un display specifico o fornisci un valore predefinito in /data/system/display_settings.xml
. Per alcuni esempi,
consulta Impostazioni delle finestre di visualizzazione.
Implementazione
DisplayWindowSettings#setShouldShowSystemDecorsLocked()
è disponibile anche in
WindowManager#setShouldShowSystemDecors()
per i test. L'attivazione di questo metodo con l'intento di attivare le decorazioni di sistema non aggiunge finestre di decorazione precedentemente mancanti né le rimuove se erano presenti in precedenza. Nella maggior parte dei casi, la modifica del supporto delle decorazioni di sistema viene applicata completamente solo dopo il riavvio del dispositivo.
I controlli per il supporto delle decorazioni di sistema nella base di codice di WindowManager solitamente passano per DisplayContent#supportsSystemDecorations()
, mentre i controlli per i servizi esterni (come l'interfaccia utente di sistema per verificare se la barra di navigazione deve essere visualizzata) utilizzano WindowManager#shouldShowSystemDecors()
.
Per capire cosa viene controllato da questa impostazione, esplora i punti di chiamata di questi metodi.
Finestre di decorazione dell'interfaccia utente di sistema
Android 10 aggiunge il supporto delle finestre di arredamento del sistema solo per la barra di navigazione, perché quest'ultima è essenziale per navigare tra attività e app. Per impostazione predefinita, la barra di navigazione mostra le affordance Indietro e Home. Questo valore viene incluso solo se il display di destinazione supporta le decorazioni di sistema (vedi DisplayWindowSettings
).
La barra di stato è una finestra di sistema più complicata, in quanto contiene anche l'area notifiche, le Impostazioni rapide e la schermata di blocco. In Android 10, la barra di stato non è supportata sui display secondari. Pertanto, le notifiche, le impostazioni e un blocco tastiera completo sono disponibili solo sul display principale.
La finestra di sistema Panoramica/Recenti non è supportata sugli schermi secondari. In Android 10, AOSP mostra Recenti solo sul display predefinito e contiene le attività di tutti i display. Quando viene avviata da Recenti, per impostazione predefinita un'attività che si trovava su un display secondario viene messa in primo piano su quel display. Questo approccio presenta alcuni problemi noti, ad esempio non si aggiorna immediatamente quando le app vengono visualizzate su altre schermate.
Implementazione
Per implementare funzionalità aggiuntive dell'interfaccia utente di sistema, i produttori di dispositivi devono utilizzare un singolo componente dell'interfaccia utente di sistema che monitora l'aggiunta/rimozione di display e presenta contenuti appropriati.
Un componente dell'interfaccia utente di sistema che supporta il multi-display (MD) deve gestire i seguenti casi:
- Inizializzazione di più display all'avvio
- Display aggiunto in fase di esecuzione
- Display rimosso in fase di esecuzione
Quando l'interfaccia utente di sistema rileva l'aggiunta di un display prima di WindowManager, viene creata una condizione di gara. Questo problema può essere evitato implementando un callback personalizzato da WindowManager all'interfaccia utente di sistema quando viene aggiunto un display anziché iscriversi agli eventi DisplayManager.DisplayListener
. Per un'implementazione di riferimento, consulta CommandQueue.Callbacks#onDisplayReady
per il supporto della barra di navigazione e WallpaperManagerInternal#onDisplayReady
per gli sfondi.
Inoltre, Android 10 fornisce questi aggiornamenti:
- La classe
NavigationBarController
controlla tutte le funzionalità specifiche delle barre di navigazione. - Per visualizzare una barra di navigazione personalizzata, vedi
CarStatusBar
. TYPE_NAVIGATION_BAR
non è più limitato a una singola istanza e può essere utilizzato per display.IWindowManager#hasNavigationBar()
viene aggiornato per includere il parametrodisplayId
solo per l'interfaccia utente di sistema.
Avvio app
In Android 10, per impostazione predefinita ogni display configurato per supportare le decorazioni di sistema ha una serie di app Home dedicata per le attività di Avvio app di tipoWindowConfiguration#ACTIVITY_TYPE_HOME
. Ogni display
utilizza un'istanza separata dell'attività del programma di avvio.
Figura 1. Esempio di Avvio app multi-display per
platform/development/samples/MultiDisplay
La maggior parte dei lanci esistenti non supporta più istanze e non è ottimizzata per schermi di grandi dimensioni. Inoltre, su display secondari/esterni spesso è prevista un'esperienza diversa. Per fornire un'attività dedicata per le schermate secondarie, Android 10 introduce la categoria SECONDARY_HOME
nei filtri di intent. Le istanze di questa attività vengono utilizzate su tutti i display che supportano le decorazioni del sistema, una per display.
<activity> ... <intent-filter> <category android:name="android.intent.category.SECONDARY_HOME" /> ... </intent-filter> </activity>
L'attività deve avere una modalità di lancio che non impedisca l'esecuzione di più istanze e che debba adattarsi a schermi di dimensioni diverse. La modalità di lancio
non può essere singleInstance
o singleTask
.
Implementazione
In Android 10, RootActivityContainer#startHomeOnDisplay()
seleziona automaticamente il componente e lo scopo desiderati in base al display
in cui viene lanciata la schermata Home. RootActivityContainer#resolveSecondaryHomeActivity()
contiene la logica per cercare il componente dell'attività del programma di avvio a seconda del programma di avvio selezionato al momento e può utilizzare quello predefinito del sistema, se necessario (vedi
ActivityTaskManagerService#getSecondaryHomeIntent()
).
Limitazioni di sicurezza
Oltre alle limitazioni che si applicano alle attività sui display secondari, per evitare la possibilità che un'app dannosa crei un display virtuale con le decorazioni di sistema attive e legga informazioni sensibili dell'utente dalla superficie, il programma di avvio viene visualizzato solo sui display virtuali di proprietà del sistema. Il programma di avvio non mostra contenuti su display virtuali non di sistema.
Sfondi
In Android 10 (e versioni successive), gli sfondi sono supportati su display secondari:
Figura 2. Sfondo animato sui display interno (sopra) ed esterno (sotto)
Gli sviluppatori possono dichiarare il supporto per la funzionalità sfondo fornendo android:supportsMultipleDisplays="true"
nella definizione XML di WallpaperInfo
. Gli sviluppatori di sfondi devono anche caricare gli asset utilizzando il contesto di visualizzazione in WallpaperService.Engine#getDisplayContext()
.
Il framework crea un'istanza WallpaperService.Engine
per display, quindi ogni motore ha il proprio contesto di superficie e visualizzazione. Lo sviluppatore deve assicurarsi che ogni motore possa disegnare in modo indipendente, a frequenze diverse, rispettando VSYNC.
Selezionare gli sfondi per le singole schermate
Android 10 non fornisce il supporto diretto della piattaforma per la selezione degli sfondi per le singole schermate. Per farlo, è necessario un identificatore dello schermo stabile per mantenere le impostazioni dello sfondo per ogni display.
Display#getDisplayId()
è dinamico, quindi non vi è alcuna garanzia che un display fisico abbia lo stesso ID dopo il riavvio.
Tuttavia, Android 10 ha aggiunto DisplayInfo.mAddress
,
che contiene identificatori stabili per i display fisici e può essere utilizzato per un'implementazione
completa in futuro. Purtroppo, è troppo tardi per implementare la logica per Android 10. La soluzione suggerita:
- Utilizza l'API
WallpaperManager
per impostare gli sfondi. WallpaperManager
viene ottenuto da un oggettoContext
e ogni oggettoContext
contiene informazioni sulla visualizzazione corrispondente (Context#getDisplay()/getDisplayId()
). Pertanto, puoi otteneredisplayId
da un'istanzaWallpaperManager
senza aggiungere nuovi metodi.- A livello di framework, utilizza
displayId
ottenuto da un oggettoContext
e mappalo a un identificatore statico (ad esempio una porta di un display fisico). Utilizza l'identificatore statico per mantenere lo sfondo scelto.
Questa soluzione alternativa utilizza le implementazioni esistenti per i selettori di sfondi. Se è stata aperta su un display specifico e utilizza il contesto corretto, quando viene chiamata per impostare uno sfondo, il sistema può identificare automaticamente il display.
Se è necessario impostare lo sfondo per un display diverso da quello corrente, crea un nuovo oggetto Context
per il display di destinazione (Context#createDisplayContext
) e ottieni l'istanza WallpaperManager
da quel display.
Limitazioni di sicurezza
Il sistema non mostrerà sfondi sui display virtuali che non sono di sua proprietà. Ciò è dovuto al fatto che un'app dannosa potrebbe creare un display virtuale con funzionalità di supporto delle decorazioni di sistema attive e leggere dalla piattaforma informazioni sensibili agli utenti (ad esempio una foto personale).
Implementazione
In Android 10, le interfacce IWallpaperConnection#attachEngine()
e IWallpaperService#attach()
accettano il parametro displayId
per creare connessioni per display.
WallpaperManagerService.DisplayConnector
incapsula un motore di sfondo e una connessione per display. In WindowManager, i controller di sfondo vengono creati per ogni oggetto DisplayContent
al momento della costruzione anziché un singolo WallpaperController
per tutti i display.
Alcune implementazioni del metodo pubblico WallpaperManager
(ad esempio
WallpaperManager#getDesiredMinimumWidth()
) sono state aggiornate per calcolare
e fornire informazioni per le visualizzazioni corrispondenti.
WallpaperInfo#supportsMultipleDisplays()
e un attributo corrispondente
risorsa sono stati aggiunti in modo che gli sviluppatori di app possano segnalare quali
sfondi sono pronti per più schermi.
Se il servizio di sfondo mostrato sul display predefinito non supporta più display, il sistema mostra lo sfondo predefinito sui display secondari.
Figura 3. Logica di riserva per lo sfondo per i display secondari