As atualizações feitas nessas áreas específicas da tela são fornecidas nesta página.
Decorações do sistema
O Android 10 adiciona suporte para configurar telas secundárias para mostrar determinadas decorações do sistema, como plano de fundo, barra de navegação e tela de início. Por padrão, a tela principal mostra todas as decorações do sistema, e as secundárias mostram aquelas ativadas opcionalmente. É possível definir o suporte para um editor de método de entrada (IME) separadamente de outras decorações do sistema.
Use DisplayWindowSettings#setShouldShowSystemDecorsLocked
para adicionar suporte a decorações do sistema em uma tela específica ou fornecer
um valor padrão em /data/system/display_settings.xml. Para ver exemplos, consulte Configurações da janela de exibição.
Implementação
DisplayWindowSettings#setShouldShowSystemDecorsLocked também é exposto em
WindowManager#setShouldShowSystemDecors
para testes. Acionar esse método
com a intenção de ativar decorações do sistema não adiciona nem remove janelas de decoração que estavam
ausentes ou presentes anteriormente. Na maioria dos casos, a mudança no suporte a decorações do sistema só entra em vigor após a reinicialização do dispositivo.
As verificações de suporte a decorações do sistema na base de código do WindowManager
geralmente passam por DisplayContent#supportsSystemDecorations, enquanto
as verificações de serviços externos (como a interface do sistema para verificar se a barra de navegação
deve ser mostrada) usam WindowManager#shouldShowSystemDecors.
Para entender o que é controlado por essa configuração, confira os pontos de chamada desses métodos.
Janelas de decoração da interface do sistema
O Android 10 adiciona suporte à janela de decoração do sistema apenas para a barra de navegação, porque ela é essencial para navegar entre atividades e apps. Por padrão, a barra de navegação mostra as opções "Voltar" e "Início". A barra de navegação só é incluída se a tela de destino for compatível com decorações do sistema (consulte DisplayWindowSettings).
A barra de status é uma janela de sistema mais complicada porque também contém a aba de notificações, as configurações rápidas e a tela de bloqueio. No Android 10, a barra de status não é compatível com telas secundárias. Portanto, notificações, configurações e uma proteção de teclado completa estão disponíveis apenas na tela principal.
A janela do sistema Visão geral ou Recentes não é compatível com telas secundárias. No Android 10, o AOSP mostra a tela "Recentes" apenas no display padrão e contém atividades de todos os displays. Quando iniciada na tela "Recentes", uma atividade que estava em uma tela secundária é trazida para a frente nessa tela, por padrão. Essa abordagem tem alguns problemas conhecidos, como não atualizar imediatamente quando os apps aparecem em outras telas.
Implementação
Para implementar outros recursos da interface do sistema, os fabricantes de dispositivos precisam usar um único componente da interface do sistema que detecta a adição ou remoção de telas e apresenta o conteúdo adequado.
Um componente da interface do sistema que oferece suporte a várias telas (MD, na sigla em inglês) precisa processar os seguintes casos:
- Inicialização de várias telas na inicialização
- Tela adicionada durante a execução
- Tela removida durante a execução
Quando a interface do sistema detecta a adição de uma tela antes do WindowManager, ela cria
uma condição de disputa. Para evitar isso, implemente um callback personalizado do
WindowManager para a interface do sistema quando uma tela for adicionada em vez de se inscrever em
eventos DisplayManager.DisplayListener. Para uma implementação de referência,
consulte CommandQueue.Callbacks#onDisplayAddSystemDecorations
para suporte à barra de navegação
e WallpaperManagerInternal#onDisplayAddSystemDecorations
para planos de fundo.
Além disso, o Android 10 oferece estas atualizações:
- A classe
NavigationBarControllercontrola todas as funcionalidades específicas das barras de navegação. - Para ver uma barra de navegação personalizada, consulte
CarStatusBar. TYPE_NAVIGATION_BARnão está mais restrito a uma única instância e pode ser usado por exibição.IWindowManager#hasNavigationBaré atualizado para incluir o parâmetrodisplayIdapenas para a interface do sistema.
Launcher
No Android 10, cada tela configurada para oferecer suporte a
decorações do sistema tem uma pilha inicial dedicada para atividades de inicialização com o tipo
WindowConfiguration#ACTIVITY_TYPE_HOME, por padrão. Cada tela usa uma instância separada da atividade de inicialização:


Figura 1. Exemplo de inicializador multidispositivo para platform/development/samples/MultiDisplay.
A maioria das telas de início atuais não oferece suporte a várias instâncias e não é otimizada
para telas grandes. Além disso, um tipo diferente de experiência é esperado em telas secundárias/externas. Para fornecer uma atividade dedicada a telas
secundárias, o Android 10 introduziu a categoria SECONDARY_HOME em filtros de
intent. Instâncias dessa atividade são usadas em todas as telas compatíveis com decorações do sistema, uma para cada tela.
<activity>
...
<intent-filter>
<category android:name="android.intent.category.SECONDARY_HOME" />
...
</intent-filter>
</activity>É necessário que a atividade tenha um modo de inicialização que não impeça várias
instâncias e que possa se adaptar a diferentes tamanhos de tela. O modo de inicialização
não pode ser singleInstance nem singleTask.
Implementação
No Android 10, o RootActivityContainer#startHomeOnDisplay
seleciona automaticamente o componente e a intent desejados, dependendo da tela
em que a tela inicial é iniciada. RootActivityContainer#resolveSecondaryHomeActivity
contém a lógica para pesquisar o componente de atividade da tela de início dependendo da tela
selecionada no momento e pode usar o padrão do sistema, se necessário (consulte
ActivityTaskManagerService#getSecondaryHomeIntent).
Restrições de segurança
Além das restrições aplicadas a atividades em telas secundárias, para evitar a possibilidade de um app malicioso criar uma tela virtual com decorações do sistema ativadas e ler informações sensíveis do usuário na superfície, o iniciador só aparece em telas virtuais pertencentes ao sistema. O iniciador não mostra conteúdo em displays virtuais que não são do sistema.
Planos de fundo
No Android 10 e versões mais recentes, os planos de fundo são compatíveis com telas secundárias:


Figura 2. Plano de fundo interativo nos displays interno (acima) e externo (abaixo).
Os desenvolvedores podem declarar suporte ao recurso de plano de fundo fornecendo
android:supportsMultipleDisplays="true" na
definição XML WallpaperInfo. Os desenvolvedores de planos de fundo também precisam carregar recursos usando o contexto de exibição em WallpaperService.Engine#getDisplayContext.
A biblioteca cria uma instância WallpaperService.Engine por tela. Assim, cada mecanismo tem a própria superfície e contexto de exibição. O
desenvolvedor precisa garantir que cada mecanismo possa desenhar de forma independente, em
diferentes taxas de frames, respeitando o VSync.
Selecionar planos de fundo para telas individuais
O Android 10 não oferece suporte direto à plataforma para selecionar papéis de parede
para telas individuais. Para isso, é necessário um identificador de tela estável para manter as configurações de plano de fundo por tela.
Display#getDisplayId é dinâmico, então não há garantia de que uma tela física terá o mesmo ID após a reinicialização.
No entanto, o Android 10 adicionou DisplayInfo.mAddress,
que contém identificadores estáveis para telas físicas e pode ser usado para uma implementação
completa no futuro. Infelizmente, é tarde demais para implementar a lógica
no Android 10. A solução sugerida:
- Use a classe
WallpaperManagerpara definir os papéis de parede.WallpaperManageré obtido de um objetoContext, e cada objetoContexttem informações sobre a exibição correspondente (Context#getDisplay/getDisplayId). Portanto, é possível obterdisplayIdde uma instânciaWallpaperManagersem adicionar novos métodos. - No lado do framework, use
displayIdobtido de um objetoContexte mapeie para um identificador estático, como uma porta de um display físico. Use o identificador estático para manter o plano de fundo escolhido.
Essa solução alternativa usa implementações atuais para seletores de plano de fundo. Se ele foi aberto em uma tela específica e usa o contexto certo, quando ele chama para definir um plano de fundo, o sistema pode identificar automaticamente a tela.
Se for necessário definir um plano de fundo para uma tela diferente da atual, crie um novo objeto Context para a tela de destino (Context#createDisplayContext) e extraia a instância WallpaperManager dessa tela.
Restrições de segurança
O sistema não mostra papéis de parede em telas virtuais que não são dele. Isso ocorre devido a uma questão de segurança: um app malicioso pode criar uma tela virtual com suporte ativado para decorações do sistema e ler informações sensíveis do usuário na superfície (como uma foto pessoal).
Implementação
No Android 10, as interfaces IWallpaperConnection#attachEngine
e IWallpaperService#attach aceitam o parâmetro
displayId para criar conexões por tela.
WallpaperManagerService.DisplayConnector encapsula um mecanismo e uma conexão de plano de fundo por tela. No WindowManager, os controladores de plano de fundo são
criados para cada objeto DisplayContent na construção, em vez de um
único WallpaperController para todas as telas.
Algumas das implementações públicas do método WallpaperManager (como
WallpaperManager#getDesiredMinimumWidth) foram atualizadas para calcular
e fornecer informações para as telas correspondentes.
WallpaperInfo#supportsMultipleDisplays e um atributo de recurso correspondente foram adicionados para que os desenvolvedores de apps possam informar quais papéis de parede estão prontos para várias telas.
Se o serviço de plano de fundo mostrado na tela padrão não for compatível com várias telas, o sistema vai mostrar o plano de fundo padrão nas telas secundárias:

Figura 3. Lógica de substituição de plano de fundo para telas secundárias.
Ativar o suporte a planos de fundo interativos
No Android 10 e versões mais recentes (API 29), os desenvolvedores podem usar o atributo android:supportsMultipleDisplays
para indicar se o plano de fundo pode abranger várias telas. Em ambientes de modo janela para computador, em que a multitarefa é intensa, a renderização de planos de fundo interativos em telas externas pode afetar significativamente a sobrecarga da GPU e da memória.
Para preservar os recursos do sistema, ele não renderiza papéis de parede animados em telas conectadas por padrão. Quando um plano de fundo interativo é restrito pela configuração do sistema ou pelo manifesto do app, o sistema renderiza um plano de fundo estático alternativo.
Os OEMs podem ajustar essa experiência ativando o suporte a planos de fundo interativos para hardware sofisticado ou personalizando o substituto estático para uma aparência de marca.
Se o hardware puder renderizar várias instâncias de plano de fundo interativo, substitua a seguinte configuração:
| Caminho do recurso | frameworks/base/core/res/res/values/config.xml |
|---|---|
| Config Name | config_isLiveWallpaperSupportedInDesktopExperience |
Personalizar o plano de fundo alternativo
Se os papéis de parede animados estiverem desativados ou não forem compatíveis com o provedor, o sistema vai usar um componente padrão. Você pode apontar isso para seu próprio provedor de plano de fundo estático:
| Caminho do recurso | frameworks/base/core/res/res/values/config.xml |
|---|---|
| Config Name | fallback_wallpaper_component |
Implementar suporte a plano de fundo
Para aplicar essas mudanças, use uma sobreposição de recursos no momento da build na pasta específica do dispositivo, que
normalmente é device/<vendor>/<product>/overlay/frameworks/base/core/res/res/values/.