Android 12 introduces Wi-Fi STA/STA concurrency, which allows devices to connect to two Wi-Fi networks concurrently. This optional feature enables the following functions.
- Make-before-break: The device makes a connection to a new Wi-Fi network before breaking the existing connection. This results in smoother transitions when switching between Wi-Fi networks
- Concurrent local-only and internet connection: The device connects to a local-only network without disrupting the device's primary internet-providing connection.
- Concurrent restricted and internet connection: The device connects to a restricted network (available only to certain privileged apps) without disrupting the device's primary internet-providing connection.
- (Android 13 or higher) Concurrent multiple networks with internet connection: The device connects to two networks both of which are unrestricted and available to all apps, and provide internet connectivity.
This page describes the device behavior when this feature is enabled and the implementation details for device manufacturers and vendors.
Implementation
Devices must support the following in order to implement Wi-Fi STA/STA concurrency:
The Wi-Fi chip or firmware must support two concurrent STA connections. The firmware must support all channel and band combinations for both connections. To avoid performance issues, we recommend using a 2x2+2x2 DBS capable Wi-Fi chip.
The device must support the following APIs in the AIDL or HIDL implementation of
IWifiChip
.IWifiChip.setMultiStaPrimaryConnection(String ifName)
IWifiChip.setMultiStaUseCase(MultiStaUseCase useCase)
The HAL Wi-Fi interface combination must have two concurrent STA interfaces exposed using a specification format such as
[{STA} <= 2, ...]
. For more information, see Wi-Fi multi-interface concurrency.
If those pre-requisites are met, implement Wi-Fi STA/STA concurrency by doing the following:
Enable one or more function individually using runtime resource overlays (disabled by default).
- Make-before-break:
config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled
- Concurrent local-only and internet connection:
config_wifiMultiStaLocalOnlyConcurrencyEnabled
- Concurrent restricted and internet connection:
config_wifiMultiStaRestrictedConcurrencyEnabled
- Concurrent multiple networks with internet connection:
config_wifiMultiStaMultiInternetConcurrencyEnabled
- Make-before-break:
Validate each implementation as described in their respective sections.
To better support Wi-Fi STA/STA concurrency, we recommend that OEM-customized
frameworks and apps use the NetworkCallback#onCapabilitiesChanged()
method
instead of WifiManager#getConnectionInfo()
, which only returns WifiInfo
for
a single network and was deprecated in Android 12. For
more information, see
Wi-Fi Network Request API for peer-to-peer connectivity.
Make-before-break
The make-before-break function allows devices to connect to a new Wi-Fi network while maintaining the existing Wi-Fi network connection, only disconnecting from the old network when it successfully connects to the new Wi-Fi network and has internet access.
The make-before-break use case addresses the following problems in Android 11 or lower, where the device must disconnect from the existing Wi-Fi network before connecting to a new network (break-before-make).
When connecting to a new network, the device might discover that it has an incorrect Wi-Fi password saved or that the new network doesn't have internet access. This forces the device to switch back to the old network, leading to a significant amount of time without Wi-Fi connectivity.
The old network is disconnected abruptly, which means that all sockets get closed. Apps often don't react well to a sudden loss of connectivity and this might lead to the user experiencing a few seconds without internet connectivity until the new connection is fully established.
The default network changes twice, from the old Wi-Fi network to cellular, then from cellular to the new Wi-Fi network. This causes apps to react to network changes twice. The device must also spend a short amount of time using cellular data.
The make-before-break flow is only used for automatic Wi-Fi network switches initiated by the OS. User-initiated network switches use the legacy break-before-make flow, where the previous network is fully disconnected before the new network is connected. In certain cases, the break-before-make flow is used even in automatic switches initiated by the OS, for example, when switching between two networks both configured to use the factory MAC address.
Apps can check whether this use case is supported on the device using the
WifiManager#isMakeBeforeBreakWifiSwitchingSupported()
API.
Validate make-before-break
To validate your implementation, trigger an automatic Wi-Fi network switch (by ensuring a network with a stronger signal strength than the connected network is available) and verify that the device maintains the existing connection while connecting to the new network. To view the status of both Wi-Fi interfaces and verify that both are connected, use the following command.
adb shell wpa_cli -i wlan0 status ; echo ; adb shell wpa_cli -i wlan1 status
If the new network doesn't have connectivity, the device attempts to connect to the network, while maintaining the connection with the existing network, and aborts the attempt when it detects the new network doesn't have internet. The device then continues using the existing connection as the primary Wi-Fi network.
Concurrent local-only and internet connection
The concurrent local-only and internet connection function allows devices to
connect to a local-only connection, such as a connection to an IoT device,
concurrently with the primary internet-providing network. This function improves
the user experience when directly connecting to IoT devices, such as cameras,
which is possible through the WifiNetworkSpecifier
API added in
Android 10.
In Android 11 and lower, devices disconnect from the primary Wi-Fi network when connecting to an IoT device, resulting in a loss of internet connectivity (unless the device has another transport type available, such as cellular data).
Apps can check whether this function is supported on the device using the
WifiManager#isStaConcurrencyForLocalOnlyConnectionsSupported()
API.
For more information on changes to the concurrent local-only and internet connection function in Android 12, see Wi-Fi Network Request API for peer-to-peer connectivity.
Validate local-only and internet connection
To validate this function, use the
MultiStaConcurrencyWifiNetworkSpecifierTest
CTS test.
Concurrent restricted and internet connection
The concurrent restricted and internet connection function allows the device to concurrently connect to a primary Wi-Fi network for the user and a restricted Wi-Fi network that is only available to select apps.
Apps can check whether this function is supported on the device using the
WifiManager#isStaConcurrencyForRestrictedConnectionsSupported()
API.
To enable a device to connect to secondary restricted Wi-Fi networks, follow these steps:
Add Wi-Fi network suggestions with
setOemPaid
orsetOemPrivate
set to true.In
ConnectivityManager
, file aNetworkRequest
with the corresponding capabilities:NET_CAPABILITY_OEM_PAID
forsetOemPaid
NET_CAPABILITY_OEM_PRIVATE
forsetOemPrivate
When the device detects scan results with a network matching the OEM paid or OEM private suggestion, it automatically connects to it as a secondary network.
Validate concurrent restricted and internet connection
To validate this function, use the
MultiStaConcurrencyRestrictedWifiNetworkSuggestionTest
CTS test.
Concurrent multiple networks with internet connection
Available for Android 13 or higher, the concurrent multiple networks with internet connection feature allows the device to concurrently connect to two networks (APs) both of which are unrestricted (all apps have access) and provide internet access.
Apps can check whether this feature is supported on the device using the
WifiManager#isStaConcurrencyForMultiInternetSupported()
method.
If the feature is supported, privileged apps can enable the feature using the
WifiManager#setStaConcurrencyForMultiInternetMode(int mode)
method. The
feature has the following modes:
WifiManager#WIFI_MULTI_INTERNET_MODE_DBS_AP
: Restricts dual connections to the dual bands of a DBS AP.WifiManager#WIFI_MULTI_INTERNET_MODE_MULTI_AP
: Connects to arbitrary APs where the individual connections use different bands.WifiManager#WIFI_MULTI_INTERNET_MODE_DISABLED
: Disables the feature.
To query the currently active feature mode, use the
WifiManager#getStaConcurrencyForMultiInternetMode()
method.
When the feature is enabled, use the following steps to request an additional internet-providing Wi-Fi network.
Create a Wi-Fi network specifier using
WifiNetworkSpecifier.Builder
. Choose a band for the specifier using thesetBand()
method. Don't specify the SSID or BSSID as the additional network for the specified band is selected by the Wi-Fi framework.Using
ConnectivityManager
, create aNetworkRequest
with theNET_CAPABILITY_INTERNET
capability.Add the specifier to the network request along with a
NetworkCallback
instance to track the status of the request, and issue the request toConnectivityManager
. If a saved network with the requested band is available in the scan result, and the connection to the network is successful,NetworkCallback.onAvailable()
is invoked on the callback object.
Validate concurrent multiple networks with internet connection
To validate this function, use the following CTS test:
- CTS:
MultiStaConcurrencyMultiInternetWifiNetworkTest
Vendor Wi-Fi chip guidelines
For Wi-Fi chip vendors, use the following guidelines to support Wi-Fi STA/STA concurrency.
The Wi-Fi chip must support dual concurrent STA connections. This means it supports the following:
- Each STA interface has a unique MAC programmable by the framework.
- The secondary STA interface can be dynamically created and destroyed.
- Each STA can be connected to a different SSID (either within the same band or a different band).
- Each STA can be connected to the same SSID (either within the same band or a different band). The two STAs must never be connected to the same BSSID.
Critical features must operate on a per-interface basis and they must be available on the primary interface. The following is a list of these critical features:
Roaming must be supported on at least the primary interface (set using
IWifiChip.setMultiStaPrimaryConnection()
). If roaming is supported on both interfaces, decisions on one connection must not clash with the second concurrent connection. For example, one interface must not roam to the BSSID of the other connection.APF (and other offloads such as ARP and NS) must be supported on at least the primary interface (set using
IWifiChip.setMultiStaPrimaryConnection()
).Link layer stats must operate on a per interface basis.
The following are recommended Wi-Fi chip implementations for different concurrency scenarios:
The Wi-Fi chip must allow the framework to call
IWifiChip.setMultiStaUseCase()
with one of the following constants to specify the current function:DUAL_STA_TRANSIENT_PREFER_PRIMARY
: Specifies the Make-Before-Break function. The quality of the primary connection must be prioritized over the secondary connection.DUAL_STA_NON_TRANSIENT_UNBIASED
: Specifies the concurrent local-only and internet connection or the concurrent restricted and internet connection function. The quality of both connections must be prioritized equally.
Because dual concurrent STAs can lead to MCC, SCC, and DBS modes of operation, the vendor implementation must choose the best radio configuration when the framework calls
IWifiChip.setMultiStaUseCase()
to indicate the function. The following are general guidelines:- 2x2+2x2 DBS is preferred if available.
- Avoid 1x1+1x1 DBS if possible because of the excessive impact on connection quality. Instead, prefer MCC.
- The MCC duty cycle must be configurable by the driver or firmware for
the various functions. The framework doesn't set the MCC duty cycle
directly, but queries this information using
StaLinkLayerIfaceStats.timeSliceDutyCycleInPercent
. If using MCC, we recommend the following duty cycles between the primary and secondary connections:
DUAL_STA_TRANSIENT_PREFER_PRIMARY
: 70% primary, 30% secondary.DUAL_STA_NON_TRANSIENT_UNBIASED
: 50% primary, 50% secondary.