Selección de red

En esta página, se describe cómo Android selecciona entre las redes disponibles de forma simultánea. Este mecanismo de selección de red afecta la manera en la que Android entrega las solicitudes de red de la app y del sistema, y también influye en la forma en que Android elige la red predeterminada de una app.

Comportamiento de la selección de red

En esta sección, se describe el comportamiento de selección de red para dispositivos que ejecutan Android 12 o versiones posteriores, y para dispositivos que ejecutan Android 11 (nivel de API 30) y versiones anteriores.

Android 12

En dispositivos que ejecutan Android 12 o versiones posteriores, Android usa la clase NetworkScore para seleccionar entre las redes disponibles. Esta clase contiene marcas que toman decisiones de políticas. Cada marca representa un atributo de red que es importante para la selección de redes.

Un agente de red (NetworkAgent) usa la marca POLICY_TRANSPORT_PRIMARY para especificar que Android prefiere la red si hay varias redes del mismo transporte. Por ejemplo, un dispositivo con dos tarjetas SIM tiene un interruptor en Configuración que te permite elegir qué tarjeta SIM usar de forma predeterminada. Dentro de un transporte determinado, Android prefiere una red con la marca POLICY_TRANSPORT_PRIMARY a una red sin la marca.

Un agente de red usa la marca POLICY_EXITING para identificar una red que se espera que se desconecte. Por ejemplo, la calidad de la red Wi-Fi se degrada si un usuario se aleja del alcance de la red. Android evita usar una red con esta marca si hay otra red disponible que no la tenga. Cada agente de red puede determinar cuándo una red se degrada lo suficiente como para considerarse que se debe salir de ella.

La clase NetworkScore también permite que un agente de red declare que Android mantiene una red conectada con la marca KEEP_CONNECTED_FOR_HANDOVER y el método NetworkScore.Builder.setKeepConnectedReason. Esta marca KEEP_CONNECTED_FOR_HANDOVER ayuda a las cadenas prospectivas. Esta marca permite que un agente de red active una red en una STA de Wi-Fi secundaria sin convertirla en la red principal hasta que Android evalúe el rendimiento de la red. Si un agente de red no declara esta marca, Android cierra las redes potenciales por no atender ninguna solicitud antes de que el agente evalúe el rendimiento de una red.

Si dos redes pueden publicar un anuncio para una solicitud determinada y tienen políticas equivalentes, Android prefiere la red que publica el anuncio para la solicitud. Si ninguna red responde a la solicitud, Android elige una de las dos. Esta red seguirá siendo la preferida hasta que cambien los indicadores de política.

La función de selección de red se implementa en el módulo de conectividad del Proyecto de código abierto de Android (AOSP). La lógica de la política para la selección de redes se encuentra en la clase NetworkRanker y sus clases auxiliares. Esto significa que los fabricantes de dispositivos no pueden personalizar directamente el código de selección de red. En su lugar, deben usar las marcas en NetworkScore para transmitir información sobre las redes.

Android 11

En los dispositivos que ejecutan Android 11 o versiones anteriores, Android realiza la selección de red según un número entero que envía un agente de red (NetworkAgent). Para cada solicitud, Android selecciona la red con la puntuación numérica más alta que puede satisfacer la solicitud. Esta puntuación numérica se compone del número entero que envía el agente de la red más las bonificaciones o penalizaciones adicionales. Android aplica estas bonificaciones o penalizaciones según las condiciones, por ejemplo, si la red está validada o es una VPN. Los agentes de red se sincronizan entre sí para tomar decisiones sobre las políticas.

Si dos redes pueden publicar un anuncio para una solicitud determinada y tienen la misma puntuación numérica, el comportamiento no está definido.

Clase NetworkScore

La clase NetworkScore es fundamental para la función de selección de redes. Esta clase contiene la API y la documentación de las marcas disponibles y el método NetworkScore.Builder.setKeepConnectedReason.

Debes compilar la clase NetworkScore con su clase de compilador y pasarla al constructor NetworkAgent durante la inicialización. Puedes actualizar las puntuaciones de la red en cualquier momento con el método NetworkAgent#sendNetworkScore.

Ejemplos de implementación de agentes de red

El AOSP incluye implementaciones de ejemplo de varios agentes de red. En la siguiente lista, se proporcionan ejemplos de implementaciones:

  • TelephonyNetworkAgent: Usa la puntuación de la red para comunicar la política de redes móviles.
  • ClientModeImpl.WifiNetworkAgent: Usa la puntuación de red para comunicar la política de redes Wi-Fi. Esta implementación proporciona retrocompatibilidad con el número entero heredado para la puntuación de la red a través de la marca POLICY_EXITING.

Dispositivos que se actualizan a Android 12

Los fabricantes de dispositivos que actualicen sus dispositivos a Android 12 deben modificar sus implementaciones de agentes de red para usar la clase NetworkScore. El número entero heredado que se usa en Android 11 o versiones anteriores se pasa en NetworkScore, pero solo se usa para el registro y fines de no regresión en Android 12. En Android 12, los fabricantes de dispositivos deben expresar los cambios con marcas NetworkScore. Luego, el módulo Connectivity Mainline usa las marcas para tomar decisiones de selección de red. Los fabricantes de dispositivos que usan código para Android 11 o versiones anteriores, pero que compilan en función de la implementación en Android 12, pueden esperar errores de compilación porque los métodos para actualizar el número entero heredado se quitaron en Android 12.

En el caso de los agentes de red que usan la clase interna NetworkFactory, debes expresar el filtro de puntuación en un objeto NetworkScore que represente la puntuación más alta de una red que la fábrica pueda crear. Esto se debe a que, en Android 12, la clase NetworkFactory solo pasa las solicitudes que coinciden con los filtros de puntuación declarados en NetworkFactory, a diferencia de Android 11 y versiones anteriores, en las que pasa todas las solicitudes.

Puedes pasar un filtro para simplificar la implementación y ahorrar batería, lo que garantiza que NetworkFactory no procese todas las solicitudes. Sin embargo, si tu implementación personalizada requiere que todas las solicitudes se pasen a NetworkFactory, puedes registrar NetworkFactory.registerIgnoringScore en lugar del método NetworkFactory.register normal. Si usas este método, pasa un filtro de puntuación que represente con mayor precisión la mejor puntuación que puede crear la fábrica. Esto ahorra batería, ya que evita la evaluación de solicitudes que la fábrica no puede satisfacer.

Validación

Para verificar el comportamiento de selección de red en un dispositivo con Android, usa las siguientes pruebas:

  • Prueba de CTS de NetworkScoreTest
  • NetworkRanker prueba de unidades

La implementación incorrecta puede provocar que las apps vuelvan a redes inesperadas cuando usan NetworkCallback. Esto incluye seleccionar la red predeterminada del dispositivo (la red que el sistema envía a una app cuando usa una devolución de llamada de red, por ejemplo, con ConnectivityManager.registerDefaultNetworkCallback).

Otro posible problema con la implementación incorrecta es el agotamiento grave de la batería. Esto ocurre cuando se activa un agente de red con una puntuación que no le permite calificar para ninguna solicitud y se desactiva inmediatamente después. Si el agente se activa y desactiva repetidamente, esto puede consumir una cantidad significativa de batería.