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 da WindowManager (extensões) são um módulo opcional da plataforma Android que
ativa vários recursos da Jetpack WindowManager. O módulo é implementado
no AOSP em frameworks/base/libs/WindowManager/Jetpack
e enviado em dispositivos com suporte aos recursos da WindowManager.
Distribuição do módulo de extensões
As extensões serão compiladas em uma biblioteca .jar
e colocadas na partição system_ext
em um dispositivo se as extensões 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
.
A inclusão desses pacotes no makefile também coloca declarações em
etc/permissions/
, disponibilizando-as para os processos do aplicativo. Normalmente, os
módulos são carregados e executados como parte do processo do app durante
a execução quando usados pela biblioteca WindowManager do Jetpack, o que torna a
operação dela de forma semelhante ao código do framework do lado do cliente, conforme mostrado na figura
abaixo:
O módulo androidx.window.extensions
é o módulo de extensões atual em
desenvolvimento ativo. O androidx.window.sidecar
é um módulo legado incluído para compatibilidade com as versões mais antigas da Jetpack WindowManager,
mas o arquivo secundário não é mais mantido ativamente.
A figura a seguir mostra a lógica para determinar o uso de
androidx.window.extensions
ou androidx.window.sidecar
.
Módulos de extensões
As extensões oferecem recursos de janelas para dispositivos de tela grande dobráveis 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 componentes com
implementações padrão ou stub dos métodos na interface
WindowExtensions
se o hardware do dispositivo não oferecer suporte aos recursos correspondentes,
a menos que o recurso seja solicitado especificamente no
documento de definição de compatibilidade (CDD) 7.1.1.1.
Extensões e APIs do Jetpack
O módulo de extensões da WindowManager fornece uma plataforma de API própria, além das
APIs da plataforma pública. O módulo de extensões é desenvolvido publicamente em uma
biblioteca do Jetpack androidx.window.extensions
que não seja voltada para o desenvolvedor, para que a Jetpack WindowManager
(androidx.window
)
possa se vincular a ele durante a compilação. A superfície da API Extensions normalmente
oferece APIs de nível inferior.
As APIs que as extensões oferecem precisam ser usadas apenas pela biblioteca Jetpack WindowManager. As APIs Extensions não foram feitas para serem chamadas diretamente pelos desenvolvedores de aplicativos. A biblioteca Extensions não pode ser adicionada como uma dependência de um aplicativo no arquivo de build do Gradle para garantir a funcionalidade correta. Evite pré-compilar a biblioteca Extensions em um aplicativo diretamente. Em vez disso, use o carregamento no momento da execução para evitar o carregamento de uma mistura de classes Extensions pré-compiladas e fornecidas no momento da execução.
A Jetpack WindowManager (androidx.window
) precisa ser adicionada como uma dependência
de aplicativo e fornece as APIs públicas voltadas ao desenvolvedor, incluindo aquelas
para recursos de extensões da WindowManager. A biblioteca WindowManager carrega automaticamente
Extensões no processo do aplicativo e une as APIs de extensões de nível inferior
em abstrações de nível superior e interfaces mais
focadas. As APIs WindowManager do Jetpack seguem os padrões de desenvolvimento
moderno de aplicativos Android e têm como objetivo oferecer interoperabilidade
conveniente ao se integrarem bem com bases de código que usam outras bibliotecas
do AndroidX.
Versões e atualizações de extensões
O módulo de extensões pode ser atualizado com as atualizações anuais ou trimestrais da 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 fornecendo aos OEMs a oportunidade de adicionar acesso oficial da 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árias versões do Android.
Versão da plataforma Android | Nível da API WindowManager Extensions | Versão da API androidx.window.extensions |
---|---|---|
Android 15 | 6 | 1.5.0 (em breve) |
QPR3 do Android 14 | 5 | 1.4.0 (em breve) |
Android 14 QPR1 | 4 | 1.3.0 |
Android 14 | 3 | 1.2.0 |
QPR3 do Android 13 | 2 | 1.1.0 |
Android 13 | 1 | 1.0.0 |
Android 12L | 1 | 1.0.0 |
O nível da API Extensions (coluna central) é aumentado sempre que há uma adição à superfície de API estável (coluna à direita).
Compatibilidade com versões anteriores e posteriores
A 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 declarado da API Extensions e fornece acesso aos recursos de acordo com o nível declarado.
Para proteger um aplicativo contra falhas no momento da execução, a WindowManager também faz uma verificação de reflexão Java do ambiente de execução das APIs Extensions disponíveis de acordo com o nível declarado da API Extensions. Se houver uma incompatibilidade, a WindowManager poderá desativar o uso de extensões (parcial ou completamente) e informar os recursos relevantes como indisponíveis para o aplicativo.
As extensões da WindowManager são implementadas como um módulo system_ext
que usa
APIs particulares da plataforma para chamar o núcleo da WindowManager,
DeviceStateManager
e outros serviços do sistema na implementação dos recursos das extensões.
Não é possível manter a compatibilidade com versões de pré-lançamento das extensões
antes da versão trimestral ou anual correspondente da plataforma Android
em que as versões são finalizadas. O histórico completo das APIs de extensões pode ser
encontrado na ramificação de versão
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 aplicativos para manter a compatibilidade futura. Para garantir isso, qualquer nova versão da API Extensions só adiciona novas APIs e não remove as versões mais antigas. Como resultado, os aplicativos com versões mais antigas da WindowManager podem continuar usando as APIs Extensions mais antigas em que os apps foram compilados.
A verificação do CTS garante que, para qualquer versão declarada das APIs de extensões no dispositivo, todas as APIs dessa e das versões anteriores estejam presentes e funcionais.
Desempenho
Por padrão, o módulo de extensões é armazenado em cache em carregadores de classe do sistema que não são bootclasspath a partir do Android 14 (nível 34 da API). 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 outras chamadas de IPC são realizadas entre o cliente e o servidor.
Módulos
Incorporação de atividades
O componente Incorporação de atividades oferece um conjunto de recursos que permitem que os aplicativos organizem a apresentação da janela de atividades dentro dos limites do aplicativo pai. Isso inclui mostrar duas atividades simultaneamente lado a lado em um layout de vários painéis, facilitando a otimização de telas grandes para aplicativos legados.
O componente de incorporação de atividades precisa estar disponível em todos os dispositivos com uma
tela integrada de tamanho igual ou maior que sw600 dp
.
A incorporação de atividades também precisa ser ativada em dispositivos com suporte a conexões
de tela externa, já que o aplicativo pode ser mostrado em um tamanho maior quando telas
externas estão conectadas durante a execução.
Configuração do dispositivo
Nenhuma configuração específica do dispositivo é necessária além de ativar o módulo Extensões, conforme descrito na seção Distribuição do módulo de extensões. É recomendável ativar as extensões em todos os dispositivos com suporte ao modo de várias janelas. É provável que versões futuras do Android tornem as extensões necessárias em configurações comuns de dispositivos portáteis e de tela grande.
Informações de layout de janelas
O componente de informações de layout de janela identifica a posição e o estado da articulação em um dispositivo dobrável quando ela atravessa uma janela do aplicativo. As informações de layout de janela permitem que os aplicativos respondam e mostrem layouts otimizados no modo de mesa em dispositivos dobráveis. Consulte Fazer com que o app reconheça um dispositivo dobrável para conferir detalhes de uso.
Dispositivos Android dobráveis que incluem uma articulação que conecta áreas de painel de tela separadas ou
contínuas precisam disponibilizar as informações sobre a articulação
para os aplicativos usando WindowLayoutComponent
.
A posição e os limites da articulação precisam ser informados em relação à janela
do aplicativo identificada por um Context
transmitido para a API. Se os limites da janela
do aplicativo não se cruzarem com os limites da articulação, a articulação
DisplayFeature
não será informada. Também é aceitável não informar os recursos de exibição
quando a posição deles pode não ser informada de maneira confiável, como quando uma janela
do aplicativo pode ser movida livremente pelo usuário no modo de várias janelas ou
no modo com efeito letterbox de compatibilidade.
Para recursos de dobramento,
as atualizações de estado precisam ser informadas quando a posição da articulação muda entre os
estados estáveis. Por padrão, em um estado de tela simples, a API precisa informar
FoldingFeature.State.FLAT
.
Se o hardware do dispositivo puder ser deixado em um modo semidobrado em um estado estável, a
API precisará informar FoldingFeature.State.HALF_OPENED
.
Não há estado fechado na API, já que, nesse caso, a janela do aplicativo
não ficaria visível ou não estaria ultrapassando os limites da articulação.
Configuração do dispositivo
Para oferecer suporte à implementação do recurso de dobra, os OEMs precisam fazer o seguinte:
Configure os estados do dispositivo em
device_state_configuration.xml
para serem usados porDeviceStateManagerService
. ConsulteDeviceStateProviderImpl.java
para referência.Se as implementações padrão de
DeviceStateProvider
ouDeviceStatePolicy
não forem adequadas para o dispositivo, uma implementação personalizada poderá ser usada.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.xml
na sobreposição do dispositivo).O formato esperado da string é:
<type>-[<left>,<top>,<right>,<bottom>]
O
type
pode serfold
ouhinge
. Os valores deleft
,top
,right
ebottom
são coordenadas de pixel inteiro no espaço de coordenadas da tela na orientação de exibiçã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 internos do dispositivo usados em
DeviceStateManager
e 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 compatíveis 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 de um dispositivo dobrável típico com a tela principal no lado interno.COMMON_STATE_HALF_OPENED = 2
: o recurso de dobra está meio aberto.COMMON_STATE_FLAT = 3
: o recurso de dobra é plano. Por exemplo, pode ser o estado aberto do dispositivo dobrável típico com a tela principal no lado interno.COMMON_STATE_USE_BASE_STATE = 1000
: no Android 14, um valor que pode ser usado para estados emulados em que o estado da articulação é derivado usando o estado base, 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 fornece um conjunto de recursos que dão aos aplicativos acesso a outras telas e áreas de exibição em alguns dispositivos dobráveis e de várias telas.
O modo de tela traseira permite que um aplicativo mostre a interface de visualização da câmera na tela da capa de um dispositivo dobrável para permitir o uso da câmera principal para selfies e vídeos. Dispositivos que têm uma tela externa compatível com o Android (conforme definido pelo CDD do Android em termos de atributos como tamanho, densidade e funcionalidades de navegação disponíveis) alinhada às câmeras traseiras precisam oferecer acesso ao modo de tela traseira.
No Android 14, o modo Dual Screen permite que os aplicativos executados na tela interna de um dispositivo dobrável mostrem conteúdo adicional na tela de cobertura voltada para outros usuários. Por exemplo, a tela de cobertura 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 dobra, os OEMs precisam fazer o seguinte:
Configure os estados do dispositivo em
device_state_configuration.xml
para serem usados porDeviceStateManagerService
. ConsulteDeviceStateProviderImpl.java
para mais informações.Se a implementação padrão de
DeviceStateProvider
ouDeviceStatePolicy
não for adequada para o dispositivo, uma implementação personalizada poderá ser usada.Para dispositivos dobráveis que oferecem suporte ao modo aberto ou plano, especifique os identificadores de estado correspondentes em
com.android.internal.R.array.config_openDeviceStates
.Para dispositivos dobráveis que oferecem suporte a 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 parcialmente dobrado (a dobradiça está parcialmente 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_rearDisplayDeviceStates
paraDeviceStateManager
. - 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_deviceStateRearDisplay
para ser usado pelas extensões. - Adicione o identificador de estado em
com.android.internal.R.array.config_deviceStatesAvailableForAppRequests
para disponibilizá-lo aos aplicativos.
- Liste os estados correspondentes em
No Android 14, para dispositivos com suporte ao modo de tela duplo (simultâneo):
- Defina
com.android.internal.R.bool.config_supportsConcurrentInternalDisplays
comotrue
. - 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_deviceStateConcurrentRearDisplay
para ser usado pelas extensões se o identificador for disponibilizado para aplicativos. - Adicione o identificador de estado em
com.android.internal.R.array.config_deviceStatesAvailableForAppRequests
para disponibilizá-lo aos aplicativos.
- Defina
Verificação
Os OEMs precisam verificar as implementações para garantir o comportamento esperado em cenários comuns. Os testes e testes de CTS usando a Jetpack WindowManager estão disponíveis para OEMs para testar implementações.
Testes CTS
Para executar os testes do CTS, consulte Executar testes do CTS. Os testes
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 que tenha as opções do desenvolvedor e a depuração USB ativadas.
- Permitir que o computador depure o dispositivo.
- Abra um shell no diretório raiz do repositório androidx.
- Mude o diretório para
framework/support
. - Execute o seguinte 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.
- Permitir que o computador depure o dispositivo.
- Navegue até um teste na biblioteca de janelas do módulo de janela.
- 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 serão ignorados se o dispositivo não atender a determinadas suposições. Os resultados são salvos em um local padrão e os analistas podem escrever um script para automatizar a análise deles.