summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java19
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java8
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java71
3 files changed, 89 insertions, 9 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 161a34276..9ee9dc8dc 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -2313,31 +2313,33 @@ public class WifiConfigManager {
* Need to be called when {@link com.android.server.SystemService#onSwitchUser(int)} is invoked.
*
* @param userId The identifier of the new foreground user, after the switch.
+ * @return List of network ID's of all the private networks of the old user which will be
+ * removed from memory.
*/
- public void handleUserSwitch(int userId) {
+ public Set<Integer> handleUserSwitch(int userId) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Handling user switch for " + userId);
}
if (userId == mCurrentUserId) {
Log.w(TAG, "User already in foreground " + userId);
- return;
+ return new HashSet<>();
}
if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
saveToStore(true);
}
// Remove any private networks of the old user before switching the userId.
- clearInternalUserData(mCurrentUserId);
+ Set<Integer> removedNetworkIds = clearInternalUserData(mCurrentUserId);
mConfiguredNetworks.setNewUser(userId);
mCurrentUserId = userId;
if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
handleUserUnlockOrSwitch(mCurrentUserId);
} else {
- // Since the new user is not logged-in yet, we cannot read data from the store files
- // yet.
+ // Cannot read data from new user's CE store file before they log-in.
mPendingUnlockStoreRead = true;
Log.i(TAG, "Waiting for user unlock to load from store");
}
+ return removedNetworkIds;
}
/**
@@ -2395,18 +2397,23 @@ public class WifiConfigManager {
* - List of deleted ephemeral networks.
*
* @param userId The identifier of the current foreground user, before the switch.
+ * @return List of network ID's of all the private networks of the old user which will be
+ * removed from memory.
*/
- private void clearInternalUserData(int userId) {
+ private Set<Integer> clearInternalUserData(int userId) {
+ Set<Integer> removedNetworkIds = new HashSet<>();
// Remove any private networks of the old user before switching the userId.
for (WifiConfiguration config : getInternalConfiguredNetworks()) {
if (!config.shared && WifiConfigurationUtil.doesUidBelongToAnyProfile(
config.creatorUid, mUserManager.getProfiles(userId))) {
+ removedNetworkIds.add(config.networkId);
mConfiguredNetworks.remove(config.networkId);
}
}
mDeletedEphemeralSSIDs.clear();
mScanDetailCaches.clear();
clearLastSelectedNetwork();
+ return removedNetworkIds;
}
/**
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 612a4aa2e..a6ad779cd 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -3863,7 +3863,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
break;
case CMD_USER_SWITCH:
- mWifiConfigManager.handleUserSwitch(message.arg1);
+ Set<Integer> removedNetworkIds =
+ mWifiConfigManager.handleUserSwitch(message.arg1);
+ if (removedNetworkIds.contains(mTargetNetworkId) ||
+ removedNetworkIds.contains(mLastNetworkId)) {
+ // Disconnect and let autojoin reselect a new network
+ sendMessage(CMD_DISCONNECT);
+ }
break;
case CMD_USER_UNLOCK:
mWifiConfigManager.handleUserUnlock(message.arg1);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 40cfb9910..6ea309a7c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -1817,6 +1817,16 @@ public class WifiConfigManagerTest {
when(mWifiConfigStore.read()).thenReturn(loadStoreData);
assertTrue(mWifiConfigManager.loadFromStore());
+ // Fetch the network ID assigned to the user 1 network initially.
+ int user1NetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ List<WifiConfiguration> retrievedNetworks =
+ mWifiConfigManager.getConfiguredNetworksWithPasswords();
+ for (WifiConfiguration network : retrievedNetworks) {
+ if (network.configKey().equals(user1Network.configKey())) {
+ user1NetworkId = network.networkId;
+ }
+ }
+
// Set up the user 2 store data that is loaded at user switch.
List<WifiConfiguration> user2Networks = new ArrayList<WifiConfiguration>() {
{
@@ -1830,7 +1840,8 @@ public class WifiConfigManagerTest {
.thenReturn(newUserStoreData);
// Now switch the user to user 2 and ensure that user 1's private network has been removed.
when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
- mWifiConfigManager.handleUserSwitch(user2);
+ Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
+ assertTrue((removedNetworks.size() == 1) && (removedNetworks.contains(user1NetworkId)));
// Set the expected networks to be |sharedNetwork| and |user2Network|.
List<WifiConfiguration> expectedNetworks = new ArrayList<WifiConfiguration>() {
@@ -1841,12 +1852,68 @@ public class WifiConfigManagerTest {
};
WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
expectedNetworks, mWifiConfigManager.getConfiguredNetworksWithPasswords());
+
+ // Send another user switch indication with the same user 2. This should be ignored and
+ // hence should not remove any new networks.
+ when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
+ assertTrue(removedNetworks.isEmpty());
+ }
+
+ /**
+ * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
+ * and ensures that user switch from a user with no private networks is handled.
+ * Test scenario:
+ * 1. Load the shared networks from shared store and emptu user 1 store.
+ * 2. Switch to user 2 and ensure that no private networks were removed.
+ */
+ @Test
+ public void testHandleUserSwitchWithNoOldUserPrivateNetworks() throws Exception {
+ int user1 = TEST_DEFAULT_USER;
+ int user2 = TEST_DEFAULT_USER + 1;
+ setupUserProfiles(user2);
+
+ int appId = 674;
+
+ // Create 2 networks. 1 for user2 and 1 shared.
+ final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
+ user2Network.shared = false;
+ user2Network.creatorUid = UserHandle.getUid(user2, appId);
+ final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork();
+
+ // Set up the store data that is loaded initially.
+ List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
+ {
+ add(sharedNetwork);
+ }
+ };
+ WifiConfigStoreData loadStoreData =
+ new WifiConfigStoreData(sharedNetworks, new ArrayList<WifiConfiguration>(),
+ new HashSet<String>());
+ when(mWifiConfigStore.read()).thenReturn(loadStoreData);
+ assertTrue(mWifiConfigManager.loadFromStore());
+
+ // Set up the user 2 store data that is loaded at user switch.
+ List<WifiConfiguration> user2Networks = new ArrayList<WifiConfiguration>() {
+ {
+ add(user2Network);
+ }
+ };
+ WifiConfigStoreData newUserStoreData =
+ new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), user2Networks,
+ new HashSet<String>());
+ when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
+ .thenReturn(newUserStoreData);
+ // Now switch the user to user 2 and ensure that no private network has been removed.
+ when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
+ assertTrue(removedNetworks.isEmpty());
}
/**
* Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
* and ensures that any non current user private networks are moved to shared store file.
- * This test simultates the following test case:
+ * This test simulates the following test case:
* 1. Loads the shared networks from shared store at bootup.
* 2. Load the private networks from user store on user 1 unlock.
* 3. Switch to user 2 and ensure that the user 2's private network has been moved to user 2's