Seleção de rede

Esta página descreve como o Android seleciona redes disponíveis simultaneamente. Esse mecanismo de seleção de rede afeta como o Android atende às solicitações de rede do app e do sistema e influencia como a rede padrão de um app é escolhida.

Comportamento de seleção de rede

Esta seção descreve o comportamento de seleção de rede para dispositivos com Android 12 ou versões mais recentes e para dispositivos com o Android 11 e versões anteriores.

Android 12

Para dispositivos com o Android 12 ou versões mais recentes, o Android usa a classe NetworkScore para selecionar entre as redes disponíveis. Essa classe contém várias flags necessárias para tomar decisões de política. Cada flag representa semanticamente um atributo de uma rede que é importante para a seleção de rede.

Um agente de rede (NetworkAgent) usa a flag POLICY_TRANSPORT_PRIMARY para especificar que a rede é preferencial quando várias redes do mesmo transporte estão presentes. Um exemplo típico disso é um dispositivo dual-SIM com um interruptor nas Configurações para permitir que o usuário escolha qual dos chips usar por padrão. Em um determinado transporte, o Android prefere uma rede com a flag POLICY_TRANSPORT_PRIMARY em vez de uma rede sem a flag.

Um agente de rede usa a flag POLICY_EXITING para identificar uma rede que será desconectada em breve. Um exemplo típico é quando a qualidade de uma rede Wi-Fi se degrada à medida que o usuário se afasta do alcance da rede. O Android evita usar uma rede com essa flag se outra rede sem ela estiver disponível. Cada agente de rede individual pode determinar quando uma rede se degrada o suficiente para ser considerada encerrada.

A classe NetworkScore também permite que um agente de rede declare que uma rede seja mantida usando a flag KEEP_CONNECTED_FOR_HANDOVER e o método NetworkScore.Builder.setKeepConnectedReason. Essa flag KEEP_CONNECTED_FOR_HANDOVER é útil para redes em potencial, permitindo que um agente de rede abra uma rede em um STA Wi-Fi secundário sem torná-la a rede principal até que a performance da rede seja avaliada. Se um agente de rede não declarar essa flag, as redes em potencial serão desfeitas por não atender a nenhuma solicitação antes que o agente tenha a chance de avaliar o desempenho de uma rede.

Se duas redes podem atender a uma determinada solicitação e são equivalentes do ponto de vista da política, a seleção prefere a rede que está veiculando a solicitação. Se nenhuma rede estiver veiculando a solicitação, ela vai escolher uma das duas. Depois disso, essa rede vai continuar sendo a preferida até que as flags de política mudem.

A implementação do recurso de seleção de rede está no Módulo de conectividade no AOSP. A lógica de política para seleção de rede está na classe NetworkRanker e nas classes auxiliares. Isso significa que os fabricantes de dispositivos não podem personalizar diretamente o código de seleção de rede, mas precisam usar as flags em NetworkScore para transmitir as informações necessárias sobre as redes.

Android 11

Para dispositivos com o Android 11 ou versões anteriores, o Android executa a seleção de rede com base em um número inteiro simples enviado das implementações de um agente de rede (NetworkAgent). Para cada solicitação, o Android seleciona a rede com a maior pontuação numérica que pode atender à solicitação. Essa pontuação numérica é composta pelo número inteiro enviado pelo agente de rede, além de bônus ou penalidades adicionais com base em algumas condições (por exemplo, se a rede é validada ou se é uma VPN). Os agentes de rede individuais se sincronizam entre si para tomar decisões relacionadas à política.

Se duas redes puderem atender a determinada solicitação e tiverem a mesma pontuação numérica, o comportamento será indefinido.

Classe NetworkScore

A classe central do recurso de seleção de rede é NetworkScore. Essa classe contém a API e a documentação das flags disponíveis e o método setKeepConnectedReason.

A classe NetworkScore precisa ser criada com a classe builder dela e ser transmitida para o construtor NetworkAgent na inicialização. As pontuações de rede podem ser atualizadas a qualquer momento usando o método NetworkAgent#sendNetworkScore.

Exemplos de implementação de agente de rede

O AOSP inclui exemplos de implementações de vários agentes de rede. Confira abaixo exemplos de implementações:

  • TelephonyNetworkAgent: usa a pontuação de rede para comunicar a política de redes móveis.
  • ClientModeImpl.WifiNetworkAgent: usa a pontuação da rede para comunicar a política de redes Wi-Fi. Essa implementação inclui compatibilidade com o número inteiro legado para a pontuação de rede usando a flag POLICY_EXITING.

Upgrade de dispositivos para o Android 12

Os fabricantes de dispositivos que estão fazendo upgrade para o Android 12 precisam modificar as implementações do agente de rede para usar a classe NetworkScore. O número inteiro legado usado no Android 11 ou versões anteriores é transmitido em NetworkScore, mas é usado apenas para fins de registro e não-regressão no Android 12. No Android 12, os fabricantes de dispositivos precisam expressar as mudanças desejadas usando flags NetworkScore. O módulo Connectivity Mainline usa as flags para tomar a decisão de seleção de rede. Os fabricantes de dispositivos que usam o código para o Android 11 ou versões anteriores, mas que criam com base na implementação no Android 12, podem esperar erros de build, já que os métodos para atualizar o inteiro legado foram removidos no Android 12.

Para agentes de rede que usam a classe NetworkFactory interna, é necessário expressar o filtro de pontuação em um objeto NetworkScore que represente a pontuação mais alta de uma rede que a fábrica pode criar. Isso ocorre porque no Android 12 a classe NetworkFactory só transmite solicitações que correspondem aos filtros de pontuação declarados como NetworkFactory em vez de todas as solicitações no Android 11 e versões anteriores.

Recomendamos transmitir um filtro para facilitar a implementação e economizar bateria, para que nem todas as solicitações sejam transmitidas para NetworkFactory. No entanto, se a implementação personalizada exigir que todas as solicitações sejam transmitidas para NetworkFactory, registre NetworkFactory.registerIgnoringScore em vez do método NetworkFactory.register normal. Se você usar esse método, recomendamos transmitir um filtro de pontuação que represente com mais precisão a melhor pontuação que a fábrica pode criar para economizar bateria, não avaliando solicitações que a fábrica não pode atender.

Validação

Para verificar o comportamento da seleção de rede em um dispositivo Android, use os seguintes testes:

Uma implementação incorreta pode resultar em redes inesperadas sendo retornadas aos apps em resposta ao uso de NetworkCallback, incluindo a seleção da rede padrão do dispositivo (a rede que o sistema envia para o app quando ele usa um callback de rede com ConnectivityManager.registerDefaultNetworkCallback).

Outro possível problema com a implementação incorreta é o consumo excessivo de bateria causado por um agente de rede que é aberto com uma pontuação que não permite a qualificação para nenhuma solicitação e é desativado imediatamente depois. Se o agente for destruído e removido várias vezes, isso pode consumir muita bateria.