Seleção de rede

Esta página descreve como o Android seleciona entre 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 da seleção de rede

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

Android 12

Para dispositivos com Android 12 ou mais recente, 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 importante para a seleção.

Um agente de rede (NetworkAgent) usa a flag POLICY_TRANSPORT_PRIMARY para especificar que a rede é preferida quando várias redes do mesmo transporte estão presentes. Um exemplo típico disso é um dispositivo com dois chips e uma opção em "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 deve ser desconectada em breve. Um exemplo típico disso é quando a qualidade de uma rede Wi-Fi diminui à medida que um usuário sai do alcance dela. 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 em saída.

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 prospectivas, permitindo que um agente de rede crie uma rede em uma STA Wi-Fi secundária sem torná-la a rede principal até que o desempenho da rede seja avaliado. Se um agente de rede não declarar essa flag, as redes em potencial serão desativadas por não atenderem a nenhuma solicitação antes que o agente tenha a chance de avaliar a performance de uma rede.

Se duas redes puderem veicular uma determinada solicitação e forem equivalentes do ponto de vista da política, a seleção vai preferir a rede que está veiculando a solicitação no momento. Se nenhuma rede estiver veiculando a solicitação, ela vai escolher uma das duas, e essa rede vai continuar sendo preferida até que as flags da política mudem.

A implementação do recurso de seleção de rede está no módulo de conectividade no AOSP. A lógica da 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

Em dispositivos com Android 11 ou versões anteriores, o Android realiza 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 mais bônus ou penalidades adicionais concedidos com base em várias condições, como se a rede é validada ou se é uma VPN. Os agentes de rede individuais se sincronizam para tomar decisões de política.

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

Classe NetworkScore

A classe central para o 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 pela classe builder e transmitida ao NetworkAgent constructor 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 agentes de rede

O AOSP inclui implementações de exemplo de vários agentes de rede. Confira alguns 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 de rede para comunicar a política de redes Wi-Fi. Essa implementação inclui compatibilidade com versões anteriores do número inteiro legado para pontuação de rede usando a flag POLICY_EXITING.

Upgrade de dispositivos para o Android 12

Os fabricantes de dispositivos que fizerem 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 só é usado 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 principal de conectividade usa as flags para tomar a decisão de seleção de rede. Os fabricantes de dispositivos que usam código para Android 11 ou versões anteriores, mas criam com base na implementação do Android 12, podem esperar erros de build, já que os métodos para atualizar o número inteiro legado foram removidos no Android 12.

Para agentes de rede que usam a classe interna NetworkFactory, eles precisam expressar o filtro de pontuação em um objeto NetworkScore que representa a pontuação mais alta de uma rede que a fábrica pode criar. Isso acontece porque, no Android 12, a classe NetworkFactory só transmite solicitações que correspondem aos filtros de pontuação declarados para NetworkFactory em vez de todas as solicitações no Android 11 e em 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 sua 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, evitando avaliar 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 no retorno de redes inesperadas para 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 problema possível com a implementação incorreta é o consumo excessivo de bateria causado por um agente de rede que é ativado com uma pontuação que não o permite se qualificar para qualquer solicitação e é desativado imediatamente depois. Se o agente for ativado e desativado repetidamente, isso poderá consumir muita bateria.