Selección de red

En esta página, se describe el modo en que Android selecciona entre redes disponibles en simultáneo. 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 se 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 y versiones anteriores.

Android 12

En el caso de los dispositivos que ejecutan Android 12 o versiones posteriores, Android usa la clase NetworkScore para seleccionar entre las redes disponibles. Esta clase contiene una serie de marcas necesarias para tomar decisiones sobre políticas. Cada marca representa semánticamente un atributo de una red que es importante para la selección de red.

Un agente de red (NetworkAgent) usa la marca POLICY_TRANSPORT_PRIMARY para especificar que la red es preferida cuando hay varias redes del mismo transporte. Un ejemplo típico es un dispositivo SIM doble con un interruptor en la Configuración que le permite al usuario elegir cuál de las tarjetas SIM usar de forma predeterminada. Dentro de un transporte determinado, Android prefiere una red con la marca POLICY_TRANSPORT_PRIMARY en lugar de una sin la marca.

Un agente de red usa la marca POLICY_EXITING para identificar una red que se espera que se desconecte pronto. Un ejemplo típico de esto es cuando la calidad de una red Wi-Fi se degrada a medida que un usuario sale del rango de la red. Android evita usar una red con esta marca si hay otra red sin esta marca disponible. Cada agente de red individual puede determinar cuándo una red se degrada lo suficiente como para que se considere que salió.

La clase NetworkScore también permite que un agente de red declare que se mantenga una red con la marca KEEP_CONNECTED_FOR_HANDOVER y el método NetworkScore.Builder.setKeepConnectedReason. Esta marca KEEP_CONNECTED_FOR_HANDOVER es útil para las redes potenciales que permiten que un agente de red muestre una red en un STA Wi-Fi secundario sin que sea la red principal hasta que se evalúe su rendimiento. Si un agente de red no declara esta marca, las redes potenciales se eliminan por no entregar ninguna solicitud antes de que el agente tenga la oportunidad de evaluar el rendimiento de una red.

Si dos redes pueden publicar una solicitud determinada y son equivalentes desde el punto de vista de la política, la selección prefiere la red que publica la solicitud actualmente. Si ninguna red entrega la solicitud, elige una de las dos, después de lo cual esta red sigue siendo preferida hasta que cambien las marcas de política.

La implementación de la función de selección de red se encuentra en el módulo de conectividad en AOSP. La lógica de la política para la selección de red 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, sino que deben usar las marcas en NetworkScore para transmitir información obligatoria sobre las redes.

Android 11

En el caso de los dispositivos que ejecutan Android 11 o versiones anteriores, Android realiza la selección de red en función de un número entero simple enviado desde las implementaciones de un agente de red (NetworkAgent). Para cada solicitud, Android selecciona la red con la puntuación numérica más alta que puede satisfacerla. Esta puntuación numérica se compone del número entero que envía el agente de red más bonificaciones o penalizaciones adicionales que se otorgan en función de una serie de condiciones, como si la red está validada o si es una VPN. Los agentes de red individuales se sincronizan entre sí para tomas decisiones de políticas.

Si dos redes pueden publicar una solicitud determinada y tienen la misma puntuación numérica, el comportamiento no se define.

Clase NetworkScore

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

La clase NetworkScore se debe compilar a través de su clase de compilador y pasar al constructor NetworkAgent durante la inicialización. Las puntuaciones de red se pueden actualizar 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. Los siguientes son ejemplos de implementaciones:

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

Dispositivos que se actualizan a Android 12

Los fabricantes de dispositivos que actualizan 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 para evitar regresiones en Android 12. En Android 12, los fabricantes de dispositivos deben expresar los cambios deseados con marcas NetworkScore. Luego, el módulo de línea principal de conectividad usa las marcas para tomar la decisión de selección de red. Los fabricantes de dispositivos que usan código para Android 11 o versiones anteriores, pero que compilan con la implementación en Android 12, pueden esperar errores de compilación, ya que 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, deben expresar su filtro de puntuación en un objeto NetworkScore que represente la puntuación más alta de una red que puede crear la fábrica. Esto se debe a que, en Android 12, la clase NetworkFactory solo pasa las solicitudes que coinciden con los filtros de puntuación declarados a NetworkFactory en lugar de todas las solicitudes en Android 11 y versiones anteriores.

Te recomendamos que pases un filtro para facilitar la implementación y ahorrar batería, de modo que no se pasen todas las solicitudes a NetworkFactory. 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, te recomendamos que pases un filtro de puntuación que represente de forma más precisa la mejor puntuación que puede crear la fábrica para ahorrar batería, ya que no evalúa las solicitudes que la fábrica no puede entregar.

Validación

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

La implementación incorrecta puede hacer que se devuelvan redes inesperadas a las apps en respuesta al uso de NetworkCallback, incluida la selección de la red predeterminada del dispositivo (la que el sistema envía a la app cuando usan una devolución de llamada de red con ConnectivityManager.registerDefaultNetworkCallback).

Otro posible problema con una implementación incorrecta es el agotamiento severo de la batería causado por un agente de red que se muestra con una puntuación que no le permite calificar para ninguna solicitud y se desmonta inmediatamente después. Si el agente se trae y derriba varias veces, esto puede consumir mucha batería.