Network selection

This page describes how Android selects among concurrently available networks. This network selection mechanism affects how Android fulfills app and system network requests and influences how Android chooses the default network for an app.

Network selection behavior

This section describes network selection behavior for devices running Android 12 or higher and for devices running Android 11 (API level 30) and lower.

Android 12

For devices running Android 12 or higher, Android uses the NetworkScore class to select among available networks. This class contains flags that make policy decisions. Each flag represents a network attribute that is important for network selection.

A network agent (NetworkAgent) uses the POLICY_TRANSPORT_PRIMARY flag to specify that Android prefers the network if multiple networks of the same transport are present. For example, a dual-SIM device has a switch in Settings that lets you choose which SIM card to use by default. Within a given transport, Android prefers a network with the POLICY_TRANSPORT_PRIMARY flag over a network without the flag.

A network agent uses the POLICY_EXITING flag to identify a network that is expected to disconnect. For example, Wi-Fi network quality degrades if a user walks out of range of the network. Android avoids using a network with this flag if another network without it's available. Each network agent can determine when a network degrades enough to be considered exiting.

The NetworkScore class also lets a network agent declare that Android keeps a network connected using the KEEP_CONNECTED_FOR_HANDOVER flag and the NetworkScore.Builder.setKeepConnectedReason method. This KEEP_CONNECTED_FOR_HANDOVER flag helps prospective networks. This flag lets a network agent bring up a network on a secondary Wi-Fi STA without making it the primary network until Android evaluates the network's performance. If a network agent doesn't declare this flag, Android tears down prospective networks for not servicing any request before the agent evaluates a network's performance.

If two networks can serve a given request and have equivalent policy, Android prefers the network that is serving the request. If no network is serving the request, Android chooses one of the two. This network continues to be preferred until policy flags change.

The network selection feature is implemented in the Connectivity module in the Android Open Source Project (AOSP). The policy logic for network selection is in the NetworkRanker class and its helper classes. This means device manufacturers can't directly customize the network selection code. Instead, they must use the flags in NetworkScore to convey information about networks.

Android 11

For devices running Android 11 or lower, Android performs network selection based on an integer sent from a network agent (NetworkAgent). For each request, Android selects the network with the highest numeric score that can satisfy the request. This numeric score is composed of the integer that the network agent sends plus additional bonuses or penalties. Android applies these bonuses or penalties based on conditions, for example, whether the network is validated or a VPN. Network agents synchronize with each other to make policy decisions.

If two networks can serve a given request and have the same numeric score, the behavior is undefined.

NetworkScore class

The NetworkScore class is central to the network selection feature. This class contains the API and documentation for the available flags and the NetworkScore.Builder.setKeepConnectedReason method.

You must build the NetworkScore class using its builder class and pass it to the NetworkAgent constructor during initialization. You can update network scores at any time using the NetworkAgent#sendNetworkScore method.

Network agent implementation examples

AOSP includes example implementations of various network agents. The following list provides example implementations:

  • TelephonyNetworkAgent: Uses network score to communicate policy for mobile networks.
  • ClientModeImpl.WifiNetworkAgent: Uses network score to communicate policy for Wi-Fi networks. This implementation provides backward compatibility with the legacy integer for network score by using the POLICY_EXITING flag.

Devices upgrading to Android 12

Device manufacturers upgrading their devices to Android 12 must modify their network agent implementations to use the NetworkScore class. The legacy integer used in Android 11 or lower is passed in NetworkScore but is only used for logging and non-regression purposes in Android 12. In Android 12, device manufacturers must express changes using NetworkScore flags. The Connectivity Mainline module then uses the flags to make network selection decisions. Device manufacturers using code for Android 11 or lower but building against the implementation in Android 12 can expect build errors because the methods for updating the legacy integer were removed in Android 12.

For network agents that use the internal NetworkFactory class, you must express the score filter in a NetworkScore object that represents the strongest score of a network the factory can create. This is because in Android 12, the NetworkFactory class only passes requests that match the score filters declared to NetworkFactory, unlike in Android 11 and lower, where it passes all requests.

You can pass a filter to simplify implementation and save battery, which ensures that NetworkFactory does not process all requests. However, if your custom implementation requires that all requests be passed to NetworkFactory, you can register NetworkFactory.registerIgnoringScore instead of the regular NetworkFactory.register method. If you use this method, pass a score filter that most accurately represents the best score the factory can create. This saves battery by preventing evaluation of requests that the factory can't fulfill.

Validation

To verify network selection behavior on an Android-powered device, use the following tests:

  • NetworkScoreTest CTS test
  • NetworkRanker unit test

Incorrect implementation might result in unexpected networks returning to apps when they use NetworkCallback. This includes selecting the device's default network (the network the system sends to an app when it uses a network callback, for example, with ConnectivityManager.registerDefaultNetworkCallback).

Another possible issue with incorrect implementation is severe battery drain. This occurs when a network agent is brought up with a score that doesn't let it qualify for any request and is torn down immediately after. If the agent repeatedly brings up and tears down, this can consume significant battery.