Seleção de rede

Nesta página, descrevemos 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 o Android escolhe a rede padrão para um app.

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 (nível 30 da API) 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 flags que tomam decisões de política. Cada flag representa um atributo de rede importante para a seleção.

Um agente de rede (NetworkAgent) usa a flag POLICY_TRANSPORT_PRIMARY para especificar que o Android prefere a rede se várias redes do mesmo transporte estiverem presentes. Por exemplo, um dispositivo com dois chips tem uma chave em Configurações que permite escolher qual chip 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. Por exemplo, a qualidade da rede Wi-Fi diminui se um usuário sair do alcance dela. O Android evita usar uma rede com essa flag se outra rede sem ela estiver disponível. Cada agente de rede 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 o Android mantém uma rede conectada usando a flag KEEP_CONNECTED_FOR_HANDOVER e o método NetworkScore.Builder.setKeepConnectedReason. Essa flag KEEP_CONNECTED_FOR_HANDOVER ajuda as redes em potencial. Essa flag permite que um agente de rede inicie uma rede em uma STA Wi-Fi secundária sem torná-la a rede primária até que o Android avalie o desempenho da rede. Se um agente de rede não declarar essa flag, o Android vai desativar as redes em potencial por não atender a nenhuma solicitação antes que o agente avalie o desempenho de uma rede.

Se duas redes puderem veicular uma determinada solicitação e tiverem políticas equivalentes, o Android vai preferir a rede que está veiculando a solicitação. Se nenhuma rede estiver atendendo à solicitação, o Android vai escolher uma das duas. Essa rede continua sendo a preferida até que as flags da política mudem.

O recurso de seleção de rede é implementado no módulo de conectividade no Android Open Source Project (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. Em vez disso, eles precisam usar as flags em NetworkScore para transmitir informações sobre 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 enviado por 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 que o agente de rede envia, além de bônus ou penalidades adicionais. O Android aplica esses bônus ou penalidades com base em condições, por exemplo, se a rede é validada ou uma VPN. Os agentes de rede 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 NetworkScore é essencial para o recurso de seleção de rede. Essa classe contém a API e a documentação das flags disponíveis e do método NetworkScore.Builder.setKeepConnectedReason.

Você precisa criar a classe NetworkScore usando a classe builder dela e transmiti-la ao NetworkAgent constructor durante a inicialização. É possível atualizar as pontuações de rede 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. A lista a seguir mostra 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 oferece 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 usando flags NetworkScore. Em seguida, o módulo principal de conectividade usa as flags para tomar decisões 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 porque 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, é necessário 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. Já no Android 11 e versões anteriores, ela transmite todas as solicitações.

Você pode transmitir um filtro para simplificar a implementação e economizar bateria, o que garante que o NetworkFactory não processe todas as solicitações. 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, transmita um filtro de pontuação que represente com mais precisão a melhor pontuação que a fábrica pode criar. Isso economiza bateria, evitando a avaliação de solicitações que a fábrica não pode atender.

Validação

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

  • Teste do CTS NetworkScoreTest
  • Teste de unidade NetworkRanker

A implementação incorreta pode resultar em redes inesperadas retornando aos apps quando eles usam NetworkCallback. Isso inclui selecionar a rede padrão do dispositivo (a rede que o sistema envia a um app quando ele usa um callback de rede, por exemplo, com ConnectivityManager.registerDefaultNetworkCallback).

Outro problema possível com a implementação incorreta é o consumo excessivo da bateria. Isso acontece quando um agente de rede é criado com uma pontuação que não o qualifica para nenhuma solicitação e é desativado imediatamente depois. Se o agente for ativado e desativado repetidamente, isso pode consumir muita bateria.