diff options
4 files changed, 366 insertions, 75 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 0cad31f87..161a34276 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -2064,14 +2064,14 @@ public class WifiConfigManager { * internal ScanResult's cache {@link #mScanDetailCaches}. This is used for initiating partial * scans for the currently connected network. * - * @param networkId network ID corresponding to the network. - * @param ageInMillis only consider scan details whose timestamps are earlier than this value. + * @param networkId network ID corresponding to the network. + * @param ageInMillis only consider scan details whose timestamps are earlier than this value. * @param homeChannelFreq frequency of the currently connected network. * @return Set containing the frequencies on which this network was found, null if the network * was not found or there are no associated scan details in the cache. */ public Set<Integer> fetchChannelSetForNetworkForPartialScan(int networkId, long ageInMillis, - int homeChannelFreq) { + int homeChannelFreq) { WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return null; @@ -2281,34 +2281,22 @@ public class WifiConfigManager { } /** - * Helper method to clear internal databases. - * This method clears the: - * - List of configured networks. - * - Map of scan detail caches. - * - List of deleted ephemeral networks. - */ - private void clearInternalData() { - mConfiguredNetworks.clear(); - mDeletedEphemeralSSIDs.clear(); - mScanDetailCaches.clear(); - clearLastSelectedNetwork(); - } - - /** - * Helper method to perform the following operations during user switch: - * - Load from the new store files. + * Helper method to perform the following operations during user switch/unlock: + * - Remove private networks of the old user. + * - Load from the new user store file. * - Save the store files again to migrate any user specific networks from the shared store * to user store. + * This method assumes the user store is visible (i.e CE storage is unlocked). So, the caller + * should ensure that the stores are accessible before invocation. * - * @param userId The identifier of the new foreground user, after the switch. + * @param userId The identifier of the new foreground user, after the unlock or switch. */ - private void loadFromStoreAndMigrateAfterUserSwitch(int userId) { + private void handleUserUnlockOrSwitch(int userId) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Loading from store after user switch/unlock for " + userId); } // Switch out the user store file. - mWifiConfigStore.switchUserStore(mWifiConfigStore.createUserFile(userId)); - if (loadFromStore()) { + if (loadFromUserStoreAfterUnlockOrSwitch(userId)) { saveToStore(true); mPendingUnlockStoreRead = false; } @@ -2337,12 +2325,13 @@ public class WifiConfigManager { if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) { saveToStore(true); } - mCurrentUserId = userId; + // Remove any private networks of the old user before switching the userId. + clearInternalUserData(mCurrentUserId); mConfiguredNetworks.setNewUser(userId); - clearInternalData(); + mCurrentUserId = userId; if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) { - loadFromStoreAndMigrateAfterUserSwitch(mCurrentUserId); + handleUserUnlockOrSwitch(mCurrentUserId); } else { // Since the new user is not logged-in yet, we cannot read data from the store files // yet. @@ -2364,7 +2353,7 @@ public class WifiConfigManager { Log.v(TAG, "Handling user unlock for " + userId); } if (userId == mCurrentUserId && mPendingUnlockStoreRead) { - loadFromStoreAndMigrateAfterUserSwitch(mCurrentUserId); + handleUserUnlockOrSwitch(mCurrentUserId); } } @@ -2385,28 +2374,100 @@ public class WifiConfigManager { } /** - * Helper function to populate the internal (in-memory) data from the retrieved store (file) - * data. It also sends out the networks changed broadcast after loading all the data. + * Helper method to clear internal databases. + * This method clears the: + * - List of configured networks. + * - Map of scan detail caches. + * - List of deleted ephemeral networks. + */ + private void clearInternalData() { + mConfiguredNetworks.clear(); + mDeletedEphemeralSSIDs.clear(); + mScanDetailCaches.clear(); + clearLastSelectedNetwork(); + } + + /** + * Helper method to clear internal databases of the specified user. + * This method clears the: + * - Private configured configured networks of the specified user. + * - Map of scan detail caches. + * - List of deleted ephemeral networks. + * + * @param userId The identifier of the current foreground user, before the switch. + */ + private void clearInternalUserData(int userId) { + // 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))) { + mConfiguredNetworks.remove(config.networkId); + } + } + mDeletedEphemeralSSIDs.clear(); + mScanDetailCaches.clear(); + clearLastSelectedNetwork(); + } + + /** + * Helper function to populate the internal (in-memory) data from the retrieved shared store + * (file) data. + * + * @param configurations list of configurations retrieved from store. + */ + private void loadInternalDataFromSharedStore( + List<WifiConfiguration> configurations) { + for (WifiConfiguration configuration : configurations) { + configuration.networkId = mNextNetworkId++; + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Adding network from shared store " + configuration.configKey()); + } + mConfiguredNetworks.put(configuration); + } + } + + /** + * Helper function to populate the internal (in-memory) data from the retrieved user store + * (file) data. * * @param configurations list of configurations retrieved from store. * @param deletedEphemeralSSIDs list of ssid's representing the ephemeral networks deleted by * the user. */ - private void loadInternalData( + private void loadInternalDataFromUserStore( List<WifiConfiguration> configurations, Set<String> deletedEphemeralSSIDs) { - // Clear out all the existing in-memory lists and load the lists from what was retrieved - // from the config store. - clearInternalData(); for (WifiConfiguration configuration : configurations) { configuration.networkId = mNextNetworkId++; if (mVerboseLoggingEnabled) { - Log.v(TAG, "Adding network from store " + configuration.configKey()); + Log.v(TAG, "Adding network from user store " + configuration.configKey()); } mConfiguredNetworks.put(configuration); } for (String ssid : deletedEphemeralSSIDs) { mDeletedEphemeralSSIDs.add(ssid); } + } + + /** + * Helper function to populate the internal (in-memory) data from the retrieved stores (file) + * data. + * This method: + * 1. Clears all existing internal data. + * 2. Sends out the networks changed broadcast after loading all the data. + * + * @param sharedConfigurations list of network configurations retrieved from shared store. + * @param userConfigurations list of network configurations retrieved from user store. + * @param deletedEphemeralSSIDs list of ssid's representing the ephemeral networks deleted by + * the user. + */ + private void loadInternalData( + List<WifiConfiguration> sharedConfigurations, + List<WifiConfiguration> userConfigurations, Set<String> deletedEphemeralSSIDs) { + // Clear out all the existing in-memory lists and load the lists from what was retrieved + // from the config store. + clearInternalData(); + loadInternalDataFromSharedStore(sharedConfigurations); + loadInternalDataFromUserStore(userConfigurations, deletedEphemeralSSIDs); if (mConfiguredNetworks.sizeForAllUsers() == 0) { Log.w(TAG, "No stored networks found."); } @@ -2426,7 +2487,8 @@ public class WifiConfigManager { if (mWifiConfigStoreLegacy.areStoresPresent()) { WifiConfigStoreDataLegacy storeData = mWifiConfigStoreLegacy.read(); Log.d(TAG, "Reading from legacy store completed"); - loadInternalData(storeData.getConfigurations(), storeData.getDeletedEphemeralSSIDs()); + loadInternalData(storeData.getConfigurations(), new ArrayList<WifiConfiguration>(), + storeData.getDeletedEphemeralSSIDs()); if (!saveToStore(true)) { return false; } @@ -2444,7 +2506,6 @@ public class WifiConfigManager { * This reads all the network configurations from: * 1. Shared WifiConfigStore.xml * 2. User WifiConfigStore.xml - * 3. PerProviderSubscription.conf * * @return true on success, false otherwise. */ @@ -2452,7 +2513,6 @@ public class WifiConfigManager { if (!mWifiConfigStore.areStoresPresent()) { return migrateFromLegacyStore(); } - WifiConfigStoreData storeData; try { storeData = mWifiConfigStore.read(); @@ -2463,7 +2523,38 @@ public class WifiConfigManager { Log.wtf(TAG, "XML deserialization of store failed. All saved networks are lost!", e); return false; } - loadInternalData(storeData.getConfigurations(), storeData.getDeletedEphemeralSSIDs()); + loadInternalData(storeData.getSharedConfigurations(), storeData.getUserConfigurations(), + storeData.getDeletedEphemeralSSIDs()); + return true; + } + + /** + * Read the user config store and load the in-memory lists from the store data retrieved and + * sends out the networks changed broadcast. + * This should be used for all user switches/unlocks to only load networks from the user + * specific store and avoid reloading the shared networks. + * + * This reads all the network configurations from: + * 1. User WifiConfigStore.xml + * + * @param userId The identifier of the foreground user. + * @return true on success, false otherwise. + */ + public boolean loadFromUserStoreAfterUnlockOrSwitch(int userId) { + WifiConfigStoreData storeData; + try { + storeData = mWifiConfigStore.switchUserStoreAndRead( + mWifiConfigStore.createUserFile(userId)); + } catch (IOException e) { + Log.wtf(TAG, "Reading from new store failed. All saved private networks are lost!", e); + return false; + } catch (XmlPullParserException e) { + Log.wtf(TAG, "XML deserialization of store failed. All saved private networks are" + + "lost!", e); + return false; + } + loadInternalDataFromUserStore(storeData.getUserConfigurations(), + storeData.getDeletedEphemeralSSIDs()); return true; } @@ -2528,7 +2619,7 @@ public class WifiConfigManager { mLocalLog.dump(fd, pw, args); pw.println("WifiConfigManager - Log End ----"); pw.println("WifiConfigManager - Configured networks Begin ----"); - for (WifiConfiguration network: getInternalConfiguredNetworks()) { + for (WifiConfiguration network : getInternalConfiguredNetworks()) { pw.println(network); } pw.println("WifiConfigManager - Configured networks End ----"); diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index e75d916aa..9a48f894b 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -261,22 +261,31 @@ public class WifiConfigStore { byte[] sharedDataBytes = mSharedStore.readRawData(); byte[] userDataBytes = mUserStore.readRawData(); long readTime = mClock.getElapsedSinceBootMillis() - readStartTime; - Log.d(TAG, "Reading from stores completed in " + readTime + " ms."); return WifiConfigStoreData.parseRawData(sharedDataBytes, userDataBytes); } /** - * Handle a user switch. This changes the user specific store. + * Handles a user switch. This method changes the user specific store file and reads from the + * new user's store file. * * @param userStore StoreFile instance pointing to the user specific store file. This should * be retrieved using {@link #createUserFile(int)} method. */ - public void switchUserStore(StoreFile userStore) { + public WifiConfigStoreData switchUserStoreAndRead(StoreFile userStore) + throws XmlPullParserException, IOException { // Stop any pending buffered writes, if any. stopBufferedWriteAlarm(); mUserStore = userStore; + + // Now read from the user store file. + long readStartTime = mClock.getElapsedSinceBootMillis(); + byte[] userDataBytes = mUserStore.readRawData(); + long readTime = mClock.getElapsedSinceBootMillis() - readStartTime; + Log.d(TAG, "Reading from user store completed in " + readTime + " ms."); + + return WifiConfigStoreData.parseRawData(null, userDataBytes); } /** diff --git a/service/java/com/android/server/wifi/WifiConfigStoreData.java b/service/java/com/android/server/wifi/WifiConfigStoreData.java index bec7d920c..b55e2dc06 100644 --- a/service/java/com/android/server/wifi/WifiConfigStoreData.java +++ b/service/java/com/android/server/wifi/WifiConfigStoreData.java @@ -119,6 +119,7 @@ public class WifiConfigStoreData { * * @return List of WifiConfiguration objects corresponding to the networks. */ + @VisibleForTesting public List<WifiConfiguration> getConfigurations() { List<WifiConfiguration> configurations = new ArrayList<>(); configurations.addAll(mSharedConfigurations); @@ -131,7 +132,6 @@ public class WifiConfigStoreData { * * @return List of WifiConfiguration objects corresponding to the networks. */ - @VisibleForTesting public List<WifiConfiguration> getSharedConfigurations() { return mSharedConfigurations; } @@ -141,7 +141,6 @@ public class WifiConfigStoreData { * * @return List of WifiConfiguration objects corresponding to the networks. */ - @VisibleForTesting public List<WifiConfiguration> getUserConfigurations() { return mUserConfigurations; } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index e7364b36d..40cfb9910 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -1480,7 +1480,7 @@ public class WifiConfigManagerTest { } assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)), mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network.networkId, 1, - TEST_FREQ_LIST[4])); + TEST_FREQ_LIST[4])); } /** @@ -1625,10 +1625,10 @@ public class WifiConfigManagerTest { // The channel list fetched should include scan results from both the linked networks. assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)), mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network1.networkId, 1, - TEST_FREQ_LIST[0])); + TEST_FREQ_LIST[0])); assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)), mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network2.networkId, 1, - TEST_FREQ_LIST[0])); + TEST_FREQ_LIST[0])); } /** @@ -1691,7 +1691,166 @@ public class WifiConfigManagerTest { /** * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)} + * and ensures that any shared private networks networkId is not changed. + * Test scenario: + * 1. Load the shared networks from shared store and user 1 store. + * 2. Switch to user 2 and ensure that the shared network's Id is not changed. + */ + @Test + public void testHandleUserSwitchDoesNotChangeSharedNetworksId() throws Exception { + int user1 = TEST_DEFAULT_USER; + int user2 = TEST_DEFAULT_USER + 1; + setupUserProfiles(user2); + + int appId = 674; + + // Create 3 networks. 1 for user1, 1 for user2 and 1 shared. + final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork(); + user1Network.shared = false; + user1Network.creatorUid = UserHandle.getUid(user1, appId); + final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork(); + user2Network.shared = false; + user2Network.creatorUid = UserHandle.getUid(user2, appId); + final WifiConfiguration sharedNetwork1 = WifiConfigurationTestUtil.createPskNetwork(); + final WifiConfiguration sharedNetwork2 = WifiConfigurationTestUtil.createPskNetwork(); + + // Set up the store data that is loaded initially. + List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() { + { + add(sharedNetwork1); + add(sharedNetwork2); + } + }; + List<WifiConfiguration> user1Networks = new ArrayList<WifiConfiguration>() { + { + add(user1Network); + } + }; + WifiConfigStoreData loadStoreData = + new WifiConfigStoreData(sharedNetworks, user1Networks, new HashSet<String>()); + when(mWifiConfigStore.read()).thenReturn(loadStoreData); + assertTrue(mWifiConfigManager.loadFromStore()); + + // Fetch the network ID's assigned to the shared networks initially. + int sharedNetwork1Id = WifiConfiguration.INVALID_NETWORK_ID; + int sharedNetwork2Id = WifiConfiguration.INVALID_NETWORK_ID; + List<WifiConfiguration> retrievedNetworks = + mWifiConfigManager.getConfiguredNetworksWithPasswords(); + for (WifiConfiguration network : retrievedNetworks) { + if (network.configKey().equals(sharedNetwork1.configKey())) { + sharedNetwork1Id = network.networkId; + } else if (network.configKey().equals(sharedNetwork2.configKey())) { + sharedNetwork2Id = network.networkId; + } + } + assertTrue(sharedNetwork1Id != WifiConfiguration.INVALID_NETWORK_ID); + assertTrue(sharedNetwork2Id != WifiConfiguration.INVALID_NETWORK_ID); + + // 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 shared network's IDs have not changed. + when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true); + mWifiConfigManager.handleUserSwitch(user2); + + // Again fetch the network ID's assigned to the shared networks and ensure they have not + // changed. + int updatedSharedNetwork1Id = WifiConfiguration.INVALID_NETWORK_ID; + int updatedSharedNetwork2Id = WifiConfiguration.INVALID_NETWORK_ID; + retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords(); + for (WifiConfiguration network : retrievedNetworks) { + if (network.configKey().equals(sharedNetwork1.configKey())) { + updatedSharedNetwork1Id = network.networkId; + } else if (network.configKey().equals(sharedNetwork2.configKey())) { + updatedSharedNetwork2Id = network.networkId; + } + } + assertEquals(sharedNetwork1Id, updatedSharedNetwork1Id); + assertEquals(sharedNetwork2Id, updatedSharedNetwork2Id); + } + + /** + * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)} + * and ensures that any old user private networks are not visible anymore. + * Test scenario: + * 1. Load the shared networks from shared store and user 1 store. + * 2. Switch to user 2 and ensure that the user 1's private network has been removed. + */ + @Test + public void testHandleUserSwitchRemovesOldUserPrivateNetworks() throws Exception { + int user1 = TEST_DEFAULT_USER; + int user2 = TEST_DEFAULT_USER + 1; + setupUserProfiles(user2); + + int appId = 674; + + // Create 3 networks. 1 for user1, 1 for user2 and 1 shared. + final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork(); + user1Network.shared = false; + user1Network.creatorUid = UserHandle.getUid(user1, appId); + 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); + } + }; + List<WifiConfiguration> user1Networks = new ArrayList<WifiConfiguration>() { + { + add(user1Network); + } + }; + WifiConfigStoreData loadStoreData = + new WifiConfigStoreData(sharedNetworks, user1Networks, 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 user 1's private network has been removed. + when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true); + mWifiConfigManager.handleUserSwitch(user2); + + // Set the expected networks to be |sharedNetwork| and |user2Network|. + List<WifiConfiguration> expectedNetworks = new ArrayList<WifiConfiguration>() { + { + add(sharedNetwork); + add(user2Network); + } + }; + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + expectedNetworks, mWifiConfigManager.getConfiguredNetworksWithPasswords()); + } + + /** + * 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: + * 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 + * private store file. */ @Test public void testHandleUserSwitchPushesOtherPrivateNetworksToSharedStore() throws Exception { @@ -1710,25 +1869,44 @@ public class WifiConfigManagerTest { user2Network.creatorUid = UserHandle.getUid(user2, appId); final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork(); - // Set up the store data first that is loaded. + // Set up the shared store data that is loaded at bootup. User 2's private network + // is still in shared store because they have not yet logged-in after upgrade. List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() { { add(sharedNetwork); add(user2Network); } }; + WifiConfigStoreData loadStoreData = + new WifiConfigStoreData(sharedNetworks, new ArrayList<WifiConfiguration>(), + new HashSet<String>()); + when(mWifiConfigStore.read()).thenReturn(loadStoreData); + assertTrue(mWifiConfigManager.loadFromStore()); + + // Set up the user store data that is loaded at user unlock. List<WifiConfiguration> userNetworks = new ArrayList<WifiConfiguration>() { { add(user1Network); } }; - WifiConfigStoreData loadStoreData = - new WifiConfigStoreData(sharedNetworks, userNetworks, new HashSet<String>()); - when(mWifiConfigStore.read()).thenReturn(loadStoreData); + WifiConfigStoreData unlockLoadStoreData = + new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), userNetworks, + new HashSet<String>()); + when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class))) + .thenReturn(unlockLoadStoreData); + mWifiConfigManager.handleUserUnlock(user1); + // Capture the written data for the user 1 and ensure that it corresponds to what was + // setup. + WifiConfigStoreData writtenStoreData = captureWriteStoreData(); + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + sharedNetworks, writtenStoreData.getSharedConfigurations()); + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + userNetworks, writtenStoreData.getUserConfigurations()); - // Now switch the user to user2 + // Now switch the user to user2 and ensure that user 2's private network has been moved to + // the user store. + when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true); mWifiConfigManager.handleUserSwitch(user2); - // Set the expected network list before comparing. user1Network should be in shared data. // Note: In the real world, user1Network will no longer be visible now because it should // already be in user1's private store file. But, we're purposefully exposing it @@ -1744,11 +1922,16 @@ public class WifiConfigManagerTest { add(user2Network); } }; - // Capture the written data for the old user and ensure that it was empty. - WifiConfigStoreData writtenStoreData = captureWriteStoreData(); - assertTrue(writtenStoreData.getConfigurations().isEmpty()); + // Capture the first written data triggered for saving the old user's network + // configurations. + writtenStoreData = captureWriteStoreData(); + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + sharedNetworks, writtenStoreData.getSharedConfigurations()); + WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( + userNetworks, writtenStoreData.getUserConfigurations()); - // Now capture the next written data and ensure that user1Network is now in shared data. + // Now capture the next written data triggered after the switch and ensure that user 2's + // network is now in user store data. writtenStoreData = captureWriteStoreData(); WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( expectedSharedNetworks, writtenStoreData.getSharedConfigurations()); @@ -1767,8 +1950,8 @@ public class WifiConfigManagerTest { int user2 = TEST_DEFAULT_USER + 1; setupUserProfiles(user2); - when(mWifiConfigStore.read()).thenReturn( - new WifiConfigStoreData( + when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class))) + .thenReturn(new WifiConfigStoreData( new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(), new HashSet<String>())); @@ -1776,7 +1959,8 @@ public class WifiConfigManagerTest { when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true); mWifiConfigManager.handleUserSwitch(user2); // Ensure that the read was invoked. - mContextConfigStoreMockOrder.verify(mWifiConfigStore).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); } /** @@ -1794,20 +1978,23 @@ public class WifiConfigManagerTest { mWifiConfigManager.handleUserSwitch(user2); // Ensure that the read was not invoked. - mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); // Now try unlocking some other user (user1), this should be ignored. mWifiConfigManager.handleUserUnlock(user1); - mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); - when(mWifiConfigStore.read()).thenReturn( - new WifiConfigStoreData( + when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class))) + .thenReturn(new WifiConfigStoreData( new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(), new HashSet<String>())); // Unlock the user2 and ensure that we read the data now. mWifiConfigManager.handleUserUnlock(user2); - mContextConfigStoreMockOrder.verify(mWifiConfigStore).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); } /** @@ -1823,11 +2010,13 @@ public class WifiConfigManagerTest { // Try stopping background user2 first, this should not do anything. when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false); mWifiConfigManager.handleUserStop(user2); - mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); // Now try stopping the foreground user1, this should trigger a write to store. mWifiConfigManager.handleUserStop(user1); - mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); mContextConfigStoreMockOrder.verify(mWifiConfigStore).write( anyBoolean(), any(WifiConfigStoreData.class)); } @@ -1840,14 +2029,15 @@ public class WifiConfigManagerTest { public void testHandleUserUnlockAfterBootup() throws Exception { int user1 = TEST_DEFAULT_USER; - when(mWifiConfigStore.read()).thenReturn( - new WifiConfigStoreData( + when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class))) + .thenReturn(new WifiConfigStoreData( new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(), new HashSet<String>())); // Unlock the user1 (default user) for the first time and ensure that we read the data. mWifiConfigManager.handleUserUnlock(user1); - mContextConfigStoreMockOrder.verify(mWifiConfigStore).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); } /** @@ -1860,8 +2050,8 @@ public class WifiConfigManagerTest { int user2 = TEST_DEFAULT_USER + 1; setupUserProfiles(user2); - when(mWifiConfigStore.read()).thenReturn( - new WifiConfigStoreData( + when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class))) + .thenReturn(new WifiConfigStoreData( new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(), new HashSet<String>())); @@ -1869,11 +2059,13 @@ public class WifiConfigManagerTest { when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true); mWifiConfigManager.handleUserSwitch(user2); // Ensure that the read was invoked. - mContextConfigStoreMockOrder.verify(mWifiConfigStore).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); // Unlock the user2 again and ensure that we don't read the data now. mWifiConfigManager.handleUserUnlock(user2); - mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read(); + mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()) + .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)); } /** @@ -2653,7 +2845,7 @@ public class WifiConfigManagerTest { * Removes ephemeral network from WifiConfigManager and ensure that it was successful. */ private void verifyRemoveEphemeralNetworkFromWifiConfigManager( - WifiConfiguration configuration) throws Exception { + WifiConfiguration configuration) throws Exception { assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID)); verifyNetworkRemoveBroadcast(configuration); |