A biblioteca Jetpack WindowManager permite que os desenvolvedores de apps ofereçam suporte a novos formatos de dispositivo e ambientes de várias janelas.
As extensões do WindowManager (Extensões) são um módulo da plataforma Android ativado por inclusão que
permite vários recursos do Jetpack WindowManager. O módulo é implementado
no AOSP em
frameworks/base/libs/WindowManager/Jetpack
e enviado em dispositivos que oferecem suporte aos recursos do WindowManager.
Distribuição do módulo de extensões
As extensões são compiladas em uma biblioteca JAR e colocadas na partição system_ext
em um dispositivo se elas estiverem ativadas no makefile do dispositivo.
Para ativar as extensões em um dispositivo, adicione o seguinte ao makefile do dispositivo do produto:
$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)
Isso ativa os pacotes androidx.window.extensions e androidx.window.sidecar no dispositivo e define a propriedade persist.wm.extensions.enabled.
Incluir esses pacotes no makefile também coloca declarações em
etc/permissions/, disponibilizando-as para processos de apps. Normalmente, os
módulos são carregados e executados como parte do processo do app em
tempo de execução quando usados pela biblioteca Jetpack WindowManager, o que torna a
operação semelhante ao código do framework do lado do cliente, conforme mostrado na figura
a seguir:
Figura 1. Extensões carregadas no processo do app.
O módulo androidx.window.extensions é o módulo de extensões atual em
desenvolvimento ativo. O módulo androidx.window.sidecar é um módulo legado
incluído para compatibilidade com as primeiras versões do Jetpack WindowManager,
mas o sidecar não recebe mais manutenção ativa.
A figura a seguir mostra a lógica para determinar o uso de
androidx.window.extensions ou androidx.window.sidecar.
Figura 2. Árvore de decisão para acessar androidx.window.extensions ou androidx.window.sidecar.
Módulos de extensões
As extensões oferecem recursos de janelas para dispositivos dobráveis de tela grande e dispositivos que oferecem suporte a janelas em telas externas. As áreas de recursos incluem:
As implementações de extensões do OEM podem fornecer componentes nulos ou com
implementações padrão ou de stub dos métodos na interface
WindowExtensions se o hardware do dispositivo não for compatível com os recursos correspondentes,
a menos que o recurso seja especificamente solicitado no Documento de definição de
compatibilidade (CDD) 7.1.1.1.
Extensões e APIs do Jetpack
O módulo Extensions do WindowManager fornece a própria superfície de API, além das APIs públicas da plataforma. O módulo Extensions é desenvolvido publicamente em uma
biblioteca androidx.window.extensions
do Jetpack que não é voltada para desenvolvedores. Assim, o Jetpack WindowManager (androidx.window)
pode se vincular a ele no tempo de compilação. A superfície da API Extensions geralmente
fornece APIs de nível mais baixo.
As APIs fornecidas pelas extensões são destinadas ao uso exclusivo da biblioteca WindowManager do Jetpack. As APIs Extensions não foram criadas para serem chamadas diretamente por desenvolvedores de apps. A biblioteca Extensions não pode ser adicionada como uma dependência para um app no arquivo de build do Gradle para garantir a funcionalidade correta. Evite pré-compilar a biblioteca Extensions diretamente em um app. Em vez disso, use o carregamento no tempo de execução para evitar o carregamento de uma combinação de classes Extensions pré-compiladas e fornecidas no tempo de execução.
O Jetpack WindowManager (androidx.window) deve ser adicionado como uma dependência do app e fornece as APIs públicas voltadas para desenvolvedores, incluindo aquelas para recursos das extensões do WindowManager. A biblioteca WindowManager carrega automaticamente
as extensões no processo do app e encapsula as APIs de
extensões de nível inferior em abstrações de nível superior e interfaces
mais focadas. As APIs do WindowManager Jetpack seguem os padrões do desenvolvimento moderno de apps Android e foram criadas para oferecer interoperabilidade conveniente, integrando-se bem a bases de código que usam outras bibliotecas AndroidX.
Versões e atualizações de extensões
O módulo Extensions pode ser atualizado anualmente ou a cada trimestre com a plataforma Android. As atualizações trimestrais permitem que o nível da API Extensions seja aumentado entre as atualizações da API da plataforma Android, permitindo uma iteração mais rápida e oferecendo aos OEMs a oportunidade de adicionar acesso oficial à API a novos recursos próximos aos lançamentos de hardware.
A tabela a seguir lista as versões da API androidx.window.extensions para
vários lançamentos do Android.
| Versão da plataforma Android | Nível da API Extensions do WindowManager | Versão da API androidx.window.extensions |
|---|---|---|
| Android 15 | 6 | 1.5.0 (em breve) |
| Android 14 QPR3 | 5 | 1.4.0 (em breve) |
| Android 14 QPR1 | 4 | 1.3.0 |
| Android 14 | 3 | 1.2.0 |
| Android 13 QPR3 | 2 | 1.1.0 |
| Android 13 | 1 | 1.0.0 |
| Android 12L | 1 | 1.0.0 |
O nível da API Extensions (coluna central) aumenta sempre que há uma adição à superfície da API estável atual (coluna à direita).
Compatibilidade com versões anteriores e futuras
O Jetpack WindowManager lida com a complexidade de lidar com atualizações frequentes de nível da API, evolução rápida da API e compatibilidade com versões anteriores. Quando o código da biblioteca é executado no processo do app, a biblioteca verifica o nível da API Extensions declarado e fornece acesso aos recursos de acordo com o nível declarado.
Para evitar falhas de um app durante a execução, o WindowManager também realiza uma verificação de reflexão Java em tempo de execução das APIs Extensions disponíveis de acordo com o nível declarado da API Extensions. Se houver uma incompatibilidade, o WindowManager poderá desativar o uso de extensões (parcial ou totalmente) e informar os recursos relevantes como não disponíveis para o app.
As extensões do WindowManager são implementadas como um módulo system_ext que usa
APIs de plataforma particulares para chamar o núcleo do WindowManager,
DeviceStateManager,
e outros serviços do sistema na implementação dos recursos das extensões.
A compatibilidade pode não ser mantida com versões pré-lançamento das extensões
antes do lançamento trimestral ou anual correspondente da plataforma Android com
que as versões são finalizadas. O histórico completo das APIs Extensions pode ser encontrado na ramificação de lançamento Arquivos de texto da API window:extensions:extensions.
As versões mais recentes das extensões precisam continuar funcionando com versões mais antigas do WindowManager compiladas em apps para manter a compatibilidade futura. Para garantir isso, qualquer nova versão da API Extensions só adiciona novas APIs e não remove as mais antigas. Como resultado, apps com versões mais antigas do WindowManager podem continuar usando as APIs Extensions mais antigas com que foram compilados.
A verificação do CTS garante que, para qualquer versão declarada das APIs Extensions no dispositivo, todas as APIs dessa versão e das anteriores estejam presentes e funcionais.
Desempenho
O módulo Extensions é armazenado em cache em carregadores de classe do sistema não bootclasspath por padrão a partir do Android 14 (nível da API 34). Portanto, não há impacto no desempenho devido ao carregamento do módulo na memória na inicialização do app. O uso de recursos de módulos individuais pode ter uma pequena influência nas características de desempenho dos apps quando chamadas de IPC adicionais são realizadas entre o cliente e o servidor.
Módulos
Incorporação de atividades
O componente incorporação de atividades permite que os apps otimizem a interface para dispositivos de tela grande e displays externos. A incorporação de atividades permite apresentar duas atividades lado a lado em um layout de vários painéis, facilitando o desenvolvimento de apps adaptáveis para apps legados.
O componente de incorporação de atividades precisa estar disponível em todos os dispositivos com uma
tela integrada igual ou maior que sw600dp. A incorporação de atividades também precisa ser ativada em dispositivos que oferecem suporte a conexões de tela externa, já que o app pode ser mostrado em um tamanho maior quando telas externas são conectadas durante a execução.
Configuração do dispositivo
Não é necessário fazer nenhuma configuração específica do dispositivo além de ativar o módulo Extensions, conforme descrito na seção Distribuição do módulo Extensions. É recomendável ativar as extensões em todos os dispositivos que oferecem suporte ao modo de várias janelas. As versões futuras do Android provavelmente vão exigir extensões em configurações comuns de dispositivos portáteis e de tela grande.
Informações de layout da janela
O componente de informações de layout da janela identifica a posição e o estado da dobradiça em um dispositivo dobrável quando ela cruza uma janela do app. As informações de layout da janela permitem que os apps respondam e mostrem layouts otimizados no modo de mesa em dispositivos dobráveis. Consulte Fazer com que seu app reconheça um dispositivo dobrável para detalhes de uso.
Os dispositivos Android dobráveis que incluem uma articulação que conecta áreas separadas ou
contínuas do painel de exibição precisam disponibilizar as informações sobre a articulação
para os apps usando WindowLayoutComponent.
A posição e os limites da dobradiça precisam ser informados em relação à janela do app identificada por um Context transmitido à API. Se os limites da janela do app não se cruzarem com os limites da dobradiça, o DisplayFeature
não poderá ser informado. Também é aceitável não informar os recursos de exibição quando a posição deles não pode ser informada de maneira confiável, como quando uma janela de app pode ser movida livremente pelo usuário no modo de várias janelas ou no modo de efeito letterbox de compatibilidade.
Para recursos de dobragem,
as atualizações de estado precisam ser informadas quando a posição da dobradiça muda entre os
estados estáveis. Por padrão, em um estado de exibição simples, a API precisa informar
FoldingFeature.State.FLAT.
Se o hardware do dispositivo puder ser deixado em um modo meio dobrado em um estado estável, a
API precisará informar FoldingFeature.State.HALF_OPENED.
Não há um estado fechado na API, já que, nesse caso, a janela do app
não estaria visível ou não estaria cruzando os limites da dobradiça.
Configuração do dispositivo
Para oferecer suporte à implementação do recurso de dobragem, os OEMs precisam fazer o seguinte:
Configure os estados do dispositivo em
device_state_configuration.xmlpara serem usados peloDeviceStateManagerService. ConsulteDeviceStateProviderImpl.javapara referência.Se as implementações padrão de
DeviceStateProviderouDeviceStatePolicynão forem adequadas para o dispositivo, use uma implementação personalizada.Ative o módulo de extensões conforme descrito na seção Distribuição do módulo de extensões.
Especifique o local dos recursos de exibição no recurso de string
com.android.internal.R.string.config_display_features(geralmente emframeworks/base/core/res/res/values/config.xmlna sobreposição do dispositivo).O formato esperado para a string é:
<type>-[<left>,<top>,<right>,<bottom>]O
typepode serfoldouhinge. Os valores deleft,top,rightebottomsão coordenadas de pixel inteiras no espaço de coordenadas da tela na orientação natural. A string de configuração pode conter vários recursos de exibição separados por ponto e vírgula.Exemplo:
<!-- Jetpack WindowManager display features --> <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>Defina o mapeamento entre os identificadores de estado do dispositivo interno usados em
DeviceStateManagere as constantes de estado público enviadas aos desenvolvedores emcom.android.internal.R.array.config_device_state_postures.O formato esperado para cada entrada é:
<device_specific_state_identifier>:<Jetpack WindowManager state identifier>Os identificadores de estado aceitos são:
COMMON_STATE_NO_FOLDING_FEATURES = 1: o estado não tem recursos de dobra para informar. Por exemplo, pode ser o estado fechado do dispositivo dobrável típico com a tela principal na parte interna.COMMON_STATE_HALF_OPENED = 2: o recurso de dobra está parcialmente aberto.COMMON_STATE_FLAT = 3: o recurso de dobra está plano. Por exemplo, pode ser o estado aberto do dispositivo dobrável típico com a tela principal na parte interna.COMMON_STATE_USE_BASE_STATE = 1000: no Android 14, um valor que pode ser usado para estados emulados em que o estado da dobradiça é derivado usando o estado básico, conforme definido emCommonFoldingFeature.java.
Consulte
DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int)para mais informações.Exemplo:
<!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.--> <string-array name="config_device_state_postures" translatable="false"> <item>0:1</item> <!-- CLOSED : COMMON_STATE_NO_FOLDING_FEATURES --> <item>1:2</item> <!-- HALF_OPENED : COMMON_STATE_HALF_OPENED --> <item>2:3</item> <!-- OPENED : COMMON_STATE_FLAT --> <item>3:1</item> <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES --> <item>4:1000</item> <!-- CONCURRENT : COMMON_STATE_USE_BASE_STATE --> </string-array>
Área da janela
O componente de área da janela oferece um conjunto de recursos que dão aos apps acesso a telas e áreas de exibição extras em alguns dispositivos dobráveis e com várias telas.
O modo de tela traseira permite que um app mostre a interface de visualização da câmera na tela de capa de um dispositivo dobrável para permitir o uso da câmera principal do dispositivo para selfies e vídeos. Dispositivos que têm uma tela de cobertura compatível com Android (conforme definido pelo CDD do Android em termos de atributos como tamanho, densidade e recursos de navegação disponíveis) que se alinha às câmeras traseiras do dispositivo precisam fornecer acesso ao modo de tela traseira.
No Android 14, o modo de tela dupla permite que apps executados no display interno de um dispositivo dobrável mostrem conteúdo adicional na tela externa voltada para outros usuários. Por exemplo, a tela externa pode mostrar a visualização da câmera para a pessoa que está sendo fotografada ou gravada.
Configuração do dispositivo
Para oferecer suporte à implementação do recurso de dobragem, os OEMs precisam fazer o seguinte:
Configure os estados do dispositivo em
device_state_configuration.xmlpara serem usados peloDeviceStateManagerService. ConsulteDeviceStateProviderImpl.javapara mais informações.Se a implementação padrão de
DeviceStateProviderouDeviceStatePolicynão for adequada para o dispositivo, use uma implementação personalizada.Para dispositivos dobráveis que oferecem suporte aos modos aberto ou plano, especifique os identificadores de estado correspondentes em
com.android.internal.R.array.config_openDeviceStates.Para dispositivos dobráveis que aceitam estados dobrados, liste os identificadores de estado correspondentes em
com.android.internal.R.array.config_foldedDeviceStates.Para dispositivos dobráveis que oferecem suporte a um estado semidobrado (a dobradiça fica meio aberta como um laptop), liste os estados correspondentes em
com.android.internal.R.array.config_halfFoldedDeviceStates.Para dispositivos compatíveis com o modo de tela traseira:
- Liste os estados correspondentes em
com.android.internal.R.array.config_rearDisplayDeviceStatesparaDeviceStateManager. - Especifique o endereço de exibição física da tela traseira em
com.android.internal.R.string.config_rearDisplayPhysicalAddress. - Especifique o identificador de estado em
com.android.internal.R.integer.config_deviceStateRearDisplaypara ser usado pelas extensões. - Adicione o identificador de estado em
com.android.internal.R.array.config_deviceStatesAvailableForAppRequestspara disponibilizá-lo aos apps.
- Liste os estados correspondentes em
No Android 14, para dispositivos que oferecem suporte ao modo de tela dupla (simultânea):
- Defina
com.android.internal.R.bool.config_supportsConcurrentInternalDisplayscomotrue. - Especifique o endereço de exibição física da tela traseira em
com.android.internal.R.config_deviceStateConcurrentRearDisplay. - Especifique o identificador de estado em
com.android.internal.R.integer.config_deviceStateConcurrentRearDisplaypara ser usado pelas extensões se o identificador for disponibilizado para apps. - Adicione o identificador de estado em
com.android.internal.R.array.config_deviceStatesAvailableForAppRequestspara disponibilizá-lo aos apps.
- Defina
Verificação
Os OEMs precisam verificar as implementações para garantir o comportamento esperado em cenários comuns. Os testes do CTS e os testes usando o Jetpack WindowManager estão disponíveis para OEMs para testar implementações.
Testes do CTS
Para executar os testes do CTS, consulte Executar testes do CTS. Os testes do CTS relacionados ao Jetpack WindowManager estão em
cts/tests/framework/base/windowmanager/jetpack/.
O nome do módulo de teste é CtsWindowManagerJetpackTestCases.
Testes do WindowManager
Para fazer o download dos testes do Jetpack WindowManager, siga as instruções do Android Jetpack.
Os testes estão localizados na biblioteca de janelas no módulo window:window:
window/window/src/androidTest/.
Para executar os testes de dispositivo do módulo window:window na linha de comando, faça
o seguinte:
- Conecte um dispositivo com as opções do desenvolvedor e a depuração USB ativadas.
- Permita que o computador depure o dispositivo.
- Abra um shell no diretório raiz do repositório androidx.
- Altere o diretório para
framework/support. - Execute o comando
./gradlew window:window:connectedAndroidTest. - Analise os resultados.
Para executar os testes no Android Studio, faça o seguinte:
- Abra o Android Studio.
- Conecte um dispositivo com as opções do desenvolvedor e a depuração USB ativadas.
- Permita que o computador depure o dispositivo.
- Navegue até um teste na biblioteca de janelas do módulo de janelas.
- Abra uma classe de teste e execute usando as setas verdes no lado direito do editor.
Como alternativa, você pode criar uma configuração no Android Studio para executar um método de teste, uma classe de teste ou todos os testes em um módulo.
Os resultados podem ser analisados manualmente observando a saída do shell. Alguns testes são ignorados se o dispositivo não atender a determinadas condições. Os resultados são salvos em um local padrão, e os analistas podem escrever um script para automatizar a análise deles.