diff options
| author | 2023-04-24 21:37:40 +0000 | |
|---|---|---|
| committer | 2023-04-25 13:58:55 +0000 | |
| commit | 81e1bd8164091f9c09aa7995f6261cc6f75cdcc7 (patch) | |
| tree | 0ce810c44dcffa0a5f78de6e7a59c73114243354 | |
| parent | 99c4d1a0b3c1f56b766c9049405334ae37fece55 (diff) | |
[SB Refactor] Account for underlying wifi networks in old pipeline.
This makes `WifiStatusTracker`'s logic match the logic in
`ConnectivityRepositoryImpl`.
Bug: 225902574
Test: atest WifiStatusTrackerTest
Change-Id: I01a91e38c7b07c9891a47c4cec1ca7cabcae4f49
| -rw-r--r-- | packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java | 104 | ||||
| -rw-r--r-- | packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java | 211 |
2 files changed, 276 insertions, 39 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index 45c0d7823e99..adaf4a1d3ab5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -14,7 +14,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; @@ -26,6 +28,8 @@ import android.net.NetworkKey; import android.net.NetworkRequest; import android.net.NetworkScoreManager; import android.net.ScoredNetwork; +import android.net.TransportInfo; +import android.net.vcn.VcnTransportInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; @@ -34,8 +38,9 @@ import android.os.HandlerThread; import android.os.Looper; import android.provider.Settings; +import androidx.annotation.Nullable; + import com.android.settingslib.R; -import com.android.settingslib.Utils; import java.io.PrintWriter; import java.text.SimpleDateFormat; @@ -46,6 +51,7 @@ import java.util.Set; /** * Track status of Wi-Fi for the Sys UI. */ +@SuppressLint("MissingPermission") public class WifiStatusTracker { private static final int HISTORY_SIZE = 32; private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); @@ -66,8 +72,9 @@ public class WifiStatusTracker { private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder() .clearCapabilities() .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build(); + .addTransportType(TRANSPORT_WIFI) + .addTransportType(TRANSPORT_CELLULAR) + .build(); private final NetworkCallback mNetworkCallback = new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) { // Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable @@ -75,18 +82,10 @@ public class WifiStatusTracker { @Override public void onCapabilitiesChanged( Network network, NetworkCapabilities networkCapabilities) { - boolean isVcnOverWifi = false; - boolean isWifi = false; - WifiInfo wifiInfo = null; - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - wifiInfo = Utils.tryGetWifiInfoForVcn(networkCapabilities); - isVcnOverWifi = (wifiInfo != null); - } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo(); - isWifi = true; - } + WifiInfo wifiInfo = getMainOrUnderlyingWifiInfo(networkCapabilities); + boolean isWifi = connectionIsWifi(networkCapabilities, wifiInfo); // As long as it is a WiFi network, we will log it in the dumpsys for debugging. - if (isVcnOverWifi || isWifi) { + if (isWifi) { String log = new StringBuilder() .append(SSDF.format(System.currentTimeMillis())).append(",") .append("onCapabilitiesChanged: ") @@ -303,17 +302,8 @@ public class WifiStatusTracker { return; } NetworkCapabilities networkCapabilities; - isDefaultNetwork = false; - if (mDefaultNetworkCapabilities != null) { - boolean isWifi = mDefaultNetworkCapabilities.hasTransport( - NetworkCapabilities.TRANSPORT_WIFI); - boolean isVcnOverWifi = mDefaultNetworkCapabilities.hasTransport( - NetworkCapabilities.TRANSPORT_CELLULAR) - && (Utils.tryGetWifiInfoForVcn(mDefaultNetworkCapabilities) != null); - if (isWifi || isVcnOverWifi) { - isDefaultNetwork = true; - } - } + isDefaultNetwork = mDefaultNetworkCapabilities != null + && connectionIsWifi(mDefaultNetworkCapabilities); if (isDefaultNetwork) { // Wifi is connected and the default network. networkCapabilities = mDefaultNetworkCapabilities; @@ -352,6 +342,70 @@ public class WifiStatusTracker { ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi); } + @Nullable + private WifiInfo getMainOrUnderlyingWifiInfo(NetworkCapabilities networkCapabilities) { + WifiInfo mainWifiInfo = getMainWifiInfo(networkCapabilities); + if (mainWifiInfo != null) { + return mainWifiInfo; + } + + // Only CELLULAR networks may have underlying wifi information that's relevant to SysUI, + // so skip the underlying network check if it's not CELLULAR. + if (!networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { + return mainWifiInfo; + } + + List<Network> underlyingNetworks = networkCapabilities.getUnderlyingNetworks(); + if (underlyingNetworks == null) { + return null; + } + + // Some connections, like VPN connections, may have underlying networks that are + // eventually traced to a wifi or carrier merged connection. So, check those underlying + // networks for possible wifi information as well. See b/225902574. + for (Network underlyingNetwork : underlyingNetworks) { + NetworkCapabilities underlyingNetworkCapabilities = + mConnectivityManager.getNetworkCapabilities(underlyingNetwork); + WifiInfo underlyingWifiInfo = getMainWifiInfo(underlyingNetworkCapabilities); + if (underlyingWifiInfo != null) { + return underlyingWifiInfo; + } + } + + return null; + } + + @Nullable + private WifiInfo getMainWifiInfo(NetworkCapabilities networkCapabilities) { + boolean canHaveWifiInfo = networkCapabilities.hasTransport(TRANSPORT_WIFI) + || networkCapabilities.hasTransport(TRANSPORT_CELLULAR); + if (!canHaveWifiInfo) { + return null; + } + + TransportInfo transportInfo = networkCapabilities.getTransportInfo(); + if (transportInfo instanceof VcnTransportInfo) { + // This VcnTransportInfo logic is copied from + // [com.android.settingslib.Utils.tryGetWifiInfoForVcn]. It's copied instead of + // re-used because it makes the logic here clearer. + return ((VcnTransportInfo) transportInfo).getWifiInfo(); + } else if (transportInfo instanceof WifiInfo) { + return (WifiInfo) transportInfo; + } else { + return null; + } + } + + private boolean connectionIsWifi(NetworkCapabilities networkCapabilities) { + return connectionIsWifi( + networkCapabilities, + getMainOrUnderlyingWifiInfo(networkCapabilities)); + } + + private boolean connectionIsWifi(NetworkCapabilities networkCapabilities, WifiInfo wifiInfo) { + return wifiInfo != null || networkCapabilities.hasTransport(TRANSPORT_WIFI); + } + /** Refresh the status label on Locale changed. */ public void refreshLocale() { updateStatusLabel(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java index dc7e313dfcfa..6e975cf9d8f3 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java @@ -40,6 +40,8 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; +import java.util.Arrays; + @RunWith(RobolectricTestRunner.class) public class WifiStatusTrackerTest { @Mock Context mContext; @@ -48,13 +50,32 @@ public class WifiStatusTrackerTest { @Mock ConnectivityManager mConnectivityManager; @Mock Runnable mCallback; + private WifiStatusTracker mWifiStatusTracker; + private final ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor = ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); + private final ArgumentCaptor<ConnectivityManager.NetworkCallback> + mDefaultNetworkCallbackCaptor = + ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); + @Before public void setUp() { MockitoAnnotations.initMocks(this); + + mWifiStatusTracker = new WifiStatusTracker( + mContext, + mWifiManager, + mNetworkScoreManager, + mConnectivityManager, + mCallback); + mWifiStatusTracker.setListening(true); + + verify(mConnectivityManager) + .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any()); + verify(mConnectivityManager) + .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any()); } /** @@ -62,13 +83,6 @@ public class WifiStatusTrackerTest { */ @Test public void testWifiInfoClearedOnPrimaryNetworkLost() { - WifiStatusTracker wifiStatusTracker = new WifiStatusTracker(mContext, mWifiManager, - mNetworkScoreManager, mConnectivityManager, mCallback); - wifiStatusTracker.setListening(true); - - verify(mConnectivityManager) - .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any()); - // Trigger a validation callback for the primary Wifi network. WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class); when(primaryWifiInfo.makeCopy(anyLong())).thenReturn(primaryWifiInfo); @@ -86,8 +100,8 @@ public class WifiStatusTrackerTest { mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); // Verify primary wifi info is the one being used. - assertThat(wifiStatusTracker.connected).isTrue(); - assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi); + assertThat(mWifiStatusTracker.connected).isTrue(); + assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi); // Trigger a validation callback for the non-primary Wifi network. WifiInfo nonPrimaryWifiInfo = Mockito.mock(WifiInfo.class); @@ -106,20 +120,189 @@ public class WifiStatusTrackerTest { mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(nonPrimaryNetwork, nonPrimaryCap); // Verify primary wifi info is still the one being used. - assertThat(wifiStatusTracker.connected).isTrue(); - assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi); + assertThat(mWifiStatusTracker.connected).isTrue(); + assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi); // Lose the non-primary network. mNetworkCallbackCaptor.getValue().onLost(nonPrimaryNetwork); // Verify primary wifi info is still the one being used. - assertThat(wifiStatusTracker.connected).isTrue(); - assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi); + assertThat(mWifiStatusTracker.connected).isTrue(); + assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi); // Lose the primary network. mNetworkCallbackCaptor.getValue().onLost(primaryNetwork); // Verify we aren't connected anymore. - assertThat(wifiStatusTracker.connected).isFalse(); + assertThat(mWifiStatusTracker.connected).isFalse(); + } + + @Test + public void isCarrierMerged_typicalWifi_false() { + WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class); + when(primaryWifiInfo.isPrimary()).thenReturn(true); + + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true); + when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isCarrierMerged).isFalse(); + } + + @Test + public void isCarrierMerged_typicalCellular_false() { + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isCarrierMerged).isFalse(); + } + + @Test + public void isCarrierMerged_cellularCarrierMergedWifi_true() { + WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class); + when(primaryWifiInfo.isPrimary()).thenReturn(true); + when(primaryWifiInfo.isCarrierMerged()).thenReturn(true); + + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true); + when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isCarrierMerged).isTrue(); + } + + /** Test for b/225902574. */ + @Test + public void isCarrierMerged_cellularWithUnderlyingCarrierMergedWifi_true() { + WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class); + when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true); + when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true); + + NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class); + when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) + .thenReturn(true); + when(underlyingNetworkCapabilities.getTransportInfo()) + .thenReturn(underlyingCarrierMergedInfo); + + Network underlyingNetwork = Mockito.mock(Network.class); + when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork)) + .thenReturn(underlyingNetworkCapabilities); + + NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class); + when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) + .thenReturn(true); + when(mainCapabilities.getTransportInfo()).thenReturn(null); + when(mainCapabilities.getUnderlyingNetworks()) + .thenReturn(Arrays.asList(underlyingNetwork)); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, mainCapabilities); + + assertThat(mWifiStatusTracker.isCarrierMerged).isTrue(); + } + + @Test + public void isDefaultNetwork_typicalWifi_true() { + WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class); + when(primaryWifiInfo.isPrimary()).thenReturn(true); + + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true); + when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue(); + } + + @Test + public void isDefaultNetwork_typicalCellular_false() { + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isDefaultNetwork).isFalse(); + } + + @Test + public void isDefaultNetwork_cellularCarrierMergedWifi_true() { + WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class); + when(primaryWifiInfo.isPrimary()).thenReturn(true); + when(primaryWifiInfo.isCarrierMerged()).thenReturn(true); + + NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class); + when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true); + when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap); + + assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue(); + } + + /** Test for b/225902574. */ + @Test + public void isDefaultNetwork_cellularWithUnderlyingCarrierMergedWifi_true() { + WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class); + when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true); + when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true); + + NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class); + when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) + .thenReturn(true); + when(underlyingNetworkCapabilities.getTransportInfo()) + .thenReturn(underlyingCarrierMergedInfo); + + Network underlyingNetwork = Mockito.mock(Network.class); + when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork)) + .thenReturn(underlyingNetworkCapabilities); + + NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class); + when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) + .thenReturn(true); + when(mainCapabilities.getTransportInfo()).thenReturn(null); + when(mainCapabilities.getUnderlyingNetworks()) + .thenReturn(Arrays.asList(underlyingNetwork)); + + Network primaryNetwork = Mockito.mock(Network.class); + int primaryNetworkId = 1; + when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId); + + mDefaultNetworkCallbackCaptor.getValue() + .onCapabilitiesChanged(primaryNetwork, mainCapabilities); + + assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue(); } } |