diff options
author | Roshan Pius <rpius@google.com> | 2016-12-01 22:23:27 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-12-01 22:23:27 +0000 |
commit | 9560d5358a62b46482725ad62a4b94267e4a9893 (patch) | |
tree | 44a3d77acbd78fa99040f2bba17ecce77c3db64b | |
parent | 506ef7c01800526c9654965532648c048bbc2e86 (diff) | |
parent | 1cb361461f6ecc684761fc3940c1db622192cad1 (diff) |
WifiConfigManager: Disconnect from private network on user switch
am: 1cb361461f
Change-Id: I655871a43cf36fcd3d372bd5e63427bca8a67ad8
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 952300636..548fd6b2a 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 |