diff options
author | Steven Liu <steveliu@google.com> | 2020-03-09 15:24:01 -0700 |
---|---|---|
committer | Steven Liu <steveliu@google.com> | 2020-03-10 12:23:36 -0700 |
commit | 6f22d8135dcaf1bf8d292fa5af540240e9873319 (patch) | |
tree | 910d3579bcfe5523e8cd1ca3b5d402571176847e | |
parent | 833bdcd2c159ec52bee906a50fbc1e5e9843afe9 (diff) |
Reset carrier network connection when Default data SIM is changed.
Bug: 136607000
Test: atest com.android.server.wifi
Change-Id: I0c5c357d7c3404ff4fb9f639a8b16721baf86f04
3 files changed, 82 insertions, 47 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 6eed8166e..d3bbdfdc8 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -29,6 +29,7 @@ import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; import static com.android.server.wifi.WifiDataStall.INVALID_THROUGHPUT; import static com.android.server.wifi.WifiHealthMonitor.SCAN_RSSI_VALID_TIME_MS; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -99,6 +100,7 @@ import android.os.WorkSource; import android.provider.Settings; import android.system.OsConstants; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -140,6 +142,8 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -515,6 +519,17 @@ public class ClientModeImpl extends StateMachine { /* SIM is removed; reset any cached data for it */ static final int CMD_RESET_SIM_NETWORKS = BASE + 101; + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RESET_SIM_REASON_"}, + value = { + RESET_SIM_REASON_SIM_REMOVED, + RESET_SIM_REASON_SIM_INSERTED, + RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED}) + @interface ResetSimReason {} + static final int RESET_SIM_REASON_SIM_REMOVED = 0; + static final int RESET_SIM_REASON_SIM_INSERTED = 1; + static final int RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED = 2; + /* OSU APIs */ static final int CMD_QUERY_OSU_ICON = BASE + 104; @@ -1732,8 +1747,8 @@ public class ClientModeImpl extends StateMachine { /** * reset cached SIM credential data */ - public synchronized void resetSimAuthNetworks(boolean simPresent) { - sendMessage(CMD_RESET_SIM_NETWORKS, simPresent ? 1 : 0); + public synchronized void resetSimAuthNetworks(@ResetSimReason int resetReason) { + sendMessage(CMD_RESET_SIM_NETWORKS, resetReason); } /** @@ -4167,14 +4182,16 @@ public class ClientModeImpl extends StateMachine { break; case CMD_RESET_SIM_NETWORKS: log("resetting EAP-SIM/AKA/AKA' networks since SIM was changed"); - boolean simPresent = message.arg1 == 1; - if (simPresent) { + int resetReason = message.arg1; + if (resetReason == RESET_SIM_REASON_SIM_INSERTED) { // whenever a SIM is inserted clear all SIM related notifications mSimRequiredNotifier.dismissSimRequiredNotification(); } else { mWifiConfigManager.resetSimNetworks(); } - mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps(); + if (resetReason != RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED) { + mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps(); + } break; case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE: // If BT was connected and then turned off, there is no CONNECTION_STATE_CHANGE @@ -4869,14 +4886,15 @@ public class ClientModeImpl extends StateMachine { log(" Ignore CMD_RECONNECT request because wifi is already connected"); break; case CMD_RESET_SIM_NETWORKS: - if (message.arg1 == 0 // sim was removed + if (message.arg1 != RESET_SIM_REASON_SIM_INSERTED && mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) { WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(mLastNetworkId); - if (config.enterpriseConfig != null - && config.enterpriseConfig.isAuthenticationSimBased() - && !mTelephonyUtil.isSimPresent(mLastSubId)) { - // check if the removed sim card is associated with current config + if ((message.arg1 == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED + && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) + || (config.enterpriseConfig != null + && config.enterpriseConfig.isAuthenticationSimBased() + && !mTelephonyUtil.isSimPresent(mLastSubId))) { mWifiMetrics.logStaEvent(StaEvent.TYPE_FRAMEWORK_DISCONNECT, StaEvent.DISCONNECT_RESET_SIM_NETWORKS); diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 16d1c42c5..20ef1f7cf 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -371,7 +371,8 @@ public class WifiServiceImpl extends BaseWifiService { TelephonyManager.SIM_STATE_UNKNOWN); if (TelephonyManager.SIM_STATE_ABSENT == state) { Log.d(TAG, "resetting networks because SIM was removed"); - mClientModeImpl.resetSimAuthNetworks(false); + mClientModeImpl.resetSimAuthNetworks( + ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); } } }, @@ -385,12 +386,30 @@ public class WifiServiceImpl extends BaseWifiService { TelephonyManager.SIM_STATE_UNKNOWN); if (TelephonyManager.SIM_STATE_LOADED == state) { Log.d(TAG, "resetting networks because SIM was loaded"); - mClientModeImpl.resetSimAuthNetworks(true); + mClientModeImpl.resetSimAuthNetworks( + ClientModeImpl.RESET_SIM_REASON_SIM_INSERTED); } } }, new IntentFilter(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)); + mContext.registerReceiver( + new BroadcastReceiver() { + private int mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + @Override + public void onReceive(Context context, Intent intent) { + final int subId = intent.getIntExtra("subscription", + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + if (subId != mLastSubId) { + Log.d(TAG, "resetting networks as default data SIM is changed"); + mClientModeImpl.resetSimAuthNetworks( + ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); + mLastSubId = subId; + } + } + }, + new IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)); + // Adding optimizations of only receiving broadcasts when wifi is enabled // can result in race conditions when apps toggle wifi in the background // without active user involvement. Always receive broadcasts. diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 0edbe51bb..88893049a 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -1036,12 +1036,7 @@ public class ClientModeImplTest extends WifiBaseTest { assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); } - /** - * When the SIM card was removed, if the current wifi connection is not using it, the connection - * should be kept. - */ - @Test - public void testResetSimWhenNonConnectedSimRemoved() throws Exception { + private void setupEapSimConnection() throws Exception { mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); mConnectedNetwork.carrierId = CARRIER_ID_1; @@ -1051,8 +1046,6 @@ public class ClientModeImplTest extends WifiBaseTest { when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); - String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; - triggerConnect(); when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) @@ -1064,9 +1057,19 @@ public class ClientModeImplTest extends WifiBaseTest { mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); mLooper.dispatchAll(); + assertEquals("ObtainingIpState", getCurrentState().getName()); + } + /** + * When the SIM card was removed, if the current wifi connection is not using it, the connection + * should be kept. + */ + @Test + public void testResetSimWhenNonConnectedSimRemoved() throws Exception { + setupEapSimConnection(); doReturn(true).when(mTelephonyUtil).isSimPresent(eq(DATA_SUBID)); - mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 0); + mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, + ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); mLooper.dispatchAll(); verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), any()); @@ -1080,31 +1083,10 @@ public class ClientModeImplTest extends WifiBaseTest { */ @Test public void testResetSimWhenConnectedSimRemoved() throws Exception { - mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( - WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); - mConnectedNetwork.carrierId = CARRIER_ID_1; - doReturn(DATA_SUBID).when(mTelephonyUtil) - .getBestMatchSubscriptionId(any(WifiConfiguration.class)); - when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); - when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); - mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); - - String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; - - triggerConnect(); - - when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID)) - .thenReturn(mScanDetailCache); - when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn( - getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); - when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( - getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); - - mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); - mLooper.dispatchAll(); - + setupEapSimConnection(); doReturn(false).when(mTelephonyUtil).isSimPresent(eq(DATA_SUBID)); - mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 0); + mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, + ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); mLooper.dispatchAll(); verify(mSimRequiredNotifier).showSimRequiredNotification(any(), any()); @@ -1112,6 +1094,20 @@ public class ClientModeImplTest extends WifiBaseTest { } /** + * When the default data SIM is changed, if the current wifi connection is carrier wifi, + * the connection should be disconnected. + */ + @Test + public void testResetSimWhenDefaultDataSimChanged() throws Exception { + setupEapSimConnection(); + mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, + ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED); + mLooper.dispatchAll(); + + assertEquals("DisconnectingState", getCurrentState().getName()); + } + + /** * Tests anonymous identity is set again whenever a connection is established for the carrier * that supports encrypted IMSI and anonymous identity and no real pseudonym was provided. */ @@ -3810,7 +3806,8 @@ public class ClientModeImplTest extends WifiBaseTest { startSupplicantAndDispatchMessages(); // Indicate that sim is removed. - mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 0); + mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, + ClientModeImpl.RESET_SIM_REASON_SIM_REMOVED); mLooper.dispatchAll(); verify(mWifiConfigManager).resetSimNetworks(); @@ -3827,7 +3824,8 @@ public class ClientModeImplTest extends WifiBaseTest { startSupplicantAndDispatchMessages(); // Indicate that sim is inserted. - mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, 1); + mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, + ClientModeImpl.RESET_SIM_REASON_SIM_INSERTED); mLooper.dispatchAll(); verify(mWifiConfigManager, never()).resetSimNetworks(); |