This page describes how Android selects between concurrently available networks. This network selection mechanism affects how Android fulfills app and system network requests, and influences how the default network for an app is chosen.
Network selection behavior
This section describes the network selection behavior for devices running Android 12 or higher and for devices running Android 11 and lower.
Android 12
For devices running Android 12 or higher, Android uses
the
NetworkScore
class to select between available networks. This class contains a number of
flags required to make policy decisions. Each flag semantically represents an
attribute of a network that's important for network selection.
A network agent
(NetworkAgent
)
uses the
POLICY_TRANSPORT_PRIMARY
flag to specify that the network is preferred when multiple networks of the same
transport are present. A typical example of this is a dual-SIM device with a
switch in Settings to let the user choose which of the SIM cards 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 soon. A typical
example of this is when a Wi-Fi network quality degrades as a user walks out of
range of the network. Android avoids using a network with this flag if another
network without this flag is available. Each individual network agent can
determine when a network degrades enough to be considered exiting.
The NetworkScore
class also allows a network agent to declare that a network
be kept up using the
KEEP_CONNECTED_FOR_HANDOVER
flag and the
NetworkScore.Builder.setKeepConnectedReason
method. This
KEEP_CONNECTED_FOR_HANDOVER
flag is useful for prospective networks allowing a network agent to bring up a
network on a secondary Wi-Fi STA without making it the primary network until the
network's performance is evaluated. If a network agent doesn't declare this
flag, prospective networks are torn down for not servicing any request before
the agent has a chance to evaluate a network's performance.
If two networks can serve a given request and are equivalent from a policy point of view, the selection prefers the network that is currently serving the request. If no network is serving the request, it chooses one of the two, after which this network continues to be preferred until policy flags change.
The implementation for the network selection feature is in the
Connectivity module
in AOSP. The policy logic for network selection is found in the
NetworkRanker
class and its helper classes. This means that device manufacturers can't
directly customize the network selection code but instead must use the flags in
NetworkScore
to convey required information about networks.
Android 11
For devices running Android 11 or lower, Android performs network selection
based on a simple integer sent from the implementations of 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 sent
by the network agent plus additional bonuses or penalties given based on a
number of conditions such as whether the network is validated or whether the
network is a VPN. Individual network agents synchronize with each other in order
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 central class for the network selection feature is
NetworkScore
.
This class contains the API and documentation of the available flags and
the setKeepConnectedReason
method.
The NetworkScore
class must be built through its builder class and be passed
to the
NetworkAgent
constructor
upon initialization. Network scores can be updated at any time using the
NetworkAgent#sendNetworkScore
method.
Network agent implementation examples
AOSP includes example implementations of various network agents. The following are example implementations:
TelephonyNetworkAgent
: Uses network score to communicate policy for mobile networksClientModeImpl.WifiNetworkAgent
: Uses network score to communicate policy for Wi-Fi networks. This implementation includes backward compatibility with the legacy integer for network score using thePOLICY_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
desired changes using NetworkScore
flags. The Connectivity Mainline module
then uses the flags to make the network selection decision. Devices
manufacturers using code for Android 11 or lower but building against the
implementation in Android 12 can expect build errors
as the methods for updating the legacy integer were removed in
Android 12.
For network agents that use the internal
NetworkFactory
class, they must express their score filter in a NetworkScore
object
representing 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
instead of all requests in Android 11 and lower.
We recommend passing a filter for easier implementation and battery savings so
that not all requests are passed to NetworkFactory
. 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 using this method, we recommend passing a score filter that
represents most accurately the best score the factory can create in order to
save battery by not evaluating requests that the factory can't fulfill.
Validation
To verify the behavior of network selection on an Android device, use the following tests:
NetworkScoreTest
CTS testNetworkRanker
unit test
Incorrect implementation might result in unexpected networks being returned to
apps in response to their use of
NetworkCallback
,
including selecting the default network of the device (the network the system
sends to the app when they use a network callback with
ConnectivityManager.registerDefaultNetworkCallback
).
Another possible issue with incorrect implementation is severe battery drain caused by a network agent being brought up with a score that doesn't let it qualify for any request and being torn down immediately after. If the agent is brought up and torn down repeatedly, this could use up a lot of battery.