diff options
author | Roshan Pius <rpius@google.com> | 2016-08-22 10:35:03 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2016-08-24 13:37:44 -0700 |
commit | 3a738a26918230b2469d917dbf14323234edd39b (patch) | |
tree | 0a1e905f149374765cd760b753f243e455d21004 /service | |
parent | ee7bdc30d102e05df8d275ebc133afed21808e34 (diff) |
WifiConfigManagerNew: Migration from legacy stores
Integrated the new |WifiConfigStoreLegacy| into the new WifiConfigManager.
Every invocation of |loadFromStore| will check if there is any data to
be migrated from legacy store files if the new store files are not
present. If legacy store data is present, it will migrate all of the
data from those stores and delete them permanently.
The deletion of legacy stores is commented out in the first roll out of
the new config store changes. This will be re-enabled once things are
stable so that we can revert to this data if needed.
BUG: 29337176
Change-Id: I35d626ed8bae70c676cb10b307cb116ed837a529
TEST: Existing unit tests.
Diffstat (limited to 'service')
3 files changed, 92 insertions, 27 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManagerNew.java b/service/java/com/android/server/wifi/WifiConfigManagerNew.java index 59b66bd38..62650039d 100644 --- a/service/java/com/android/server/wifi/WifiConfigManagerNew.java +++ b/service/java/com/android/server/wifi/WifiConfigManagerNew.java @@ -43,6 +43,7 @@ import android.util.Log; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; +import com.android.server.wifi.WifiConfigStoreLegacy.WifiConfigStoreDataLegacy; import com.android.server.wifi.util.ScanResultUtil; import org.xmlpull.v1.XmlPullParserException; @@ -203,8 +204,9 @@ public class WifiConfigManagerNew { private final Clock mClock; private final UserManager mUserManager; private final BackupManagerProxy mBackupManagerProxy; - private final WifiConfigStoreNew mWifiConfigStore; private final WifiKeyStore mWifiKeyStore; + private final WifiConfigStoreNew mWifiConfigStore; + private final WifiConfigStoreLegacy mWifiConfigStoreLegacy; /** * Local log used for debugging any WifiConfigManager issues. */ @@ -263,14 +265,16 @@ public class WifiConfigManagerNew { */ WifiConfigManagerNew( Context context, FrameworkFacade facade, Clock clock, UserManager userManager, - WifiKeyStore wifiKeyStore, WifiConfigStoreNew wifiConfigStore) { + WifiKeyStore wifiKeyStore, WifiConfigStoreNew wifiConfigStore, + WifiConfigStoreLegacy wifiConfigStoreLegacy) { mContext = context; mFacade = facade; mClock = clock; mUserManager = userManager; mBackupManagerProxy = new BackupManagerProxy(); - mWifiConfigStore = wifiConfigStore; mWifiKeyStore = wifiKeyStore; + mWifiConfigStore = wifiConfigStore; + mWifiConfigStoreLegacy = wifiConfigStoreLegacy; mConfiguredNetworks = new ConfigurationMap(userManager); mScanDetailCaches = new ConcurrentHashMap<>(16, 0.75f, 2); @@ -1831,18 +1835,77 @@ public class WifiConfigManagerNew { } /** + * 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. + * + * @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( + 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 = mLastNetworkId++; + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Adding network from store " + configuration.configKey()); + } + mConfiguredNetworks.put(configuration); + } + for (String ssid : deletedEphemeralSSIDs) { + mDeletedEphemeralSSIDs.add(ssid); + } + if (mConfiguredNetworks.sizeForAllUsers() == 0) { + Log.w(TAG, "No stored networks found."); + } + sendConfiguredNetworksChangedBroadcast(); + } + + /** + * Migrate data from legacy store files. The function performs the following operations: + * 1. Check if the legacy store files are present. + * 2. If yes, read all the data from the store files. + * 3. Save it to the new store files. + * 4. Delete the legacy store file. + * + * @return true if migration was successful or not needed (fresh install), false if it failed. + */ + private boolean migrateFromLegacyStore() { + if (mWifiConfigStoreLegacy.areStoresPresent()) { + WifiConfigStoreDataLegacy storeData = mWifiConfigStoreLegacy.read(); + Log.d(TAG, "Reading from legacy store completed"); + loadInternalData(storeData.getConfigurations(), storeData.getDeletedEphemeralSSIDs()); + if (!saveToStore(true)) { + return false; + } + // TODO: Remove the legacy store files + // mWifiConfigStoreLegacy.removeStores(); + Log.d(TAG, "Migration from legacy store completed"); + } + return true; + } + + /** * Read the config store and load the in-memory lists from the store data retrieved and sends - * out the networks changed broadcast. + * out the networks changed broadcast. This method first checks if there is any data to be + * migrated from legacy store files if the new store files aren't present on the device. * * This reads all the network configurations from: * 1. Shared WifiConfigStore.xml * 2. User WifiConfigStore.xml * 3. PerProviderSubscription.conf + * * @return true on success, false otherwise. */ - private boolean loadFromStore() { - WifiConfigStoreData storeData; + @VisibleForTesting + public boolean loadFromStore() { + if (!mWifiConfigStore.areStoresPresent()) { + return migrateFromLegacyStore(); + } + WifiConfigStoreData storeData; long readStartTime = mClock.getElapsedSinceBootMillis(); try { storeData = mWifiConfigStore.read(); @@ -1854,25 +1917,9 @@ public class WifiConfigManagerNew { return false; } long readTime = mClock.getElapsedSinceBootMillis() - readStartTime; - Log.d(TAG, "Loading from store completed in " + readTime + " ms."); + Log.d(TAG, "Reading from store completed in " + readTime + " ms."); - // Clear out all the existing in-memory lists and load the lists from what was retrieved - // from the config store. - clearInternalData(); - for (WifiConfiguration configuration : storeData.getConfigurations()) { - configuration.networkId = mLastNetworkId++; - if (mVerboseLoggingEnabled) { - Log.v(TAG, "Adding network from store " + configuration.configKey()); - } - mConfiguredNetworks.put(configuration); - } - for (String ssid : storeData.getDeletedEphemeralSSIDs()) { - mDeletedEphemeralSSIDs.add(ssid); - } - if (mConfiguredNetworks.sizeForAllUsers() == 0) { - Log.w(TAG, "No stored networks found."); - } - sendConfiguredNetworksChangedBroadcast(); + loadInternalData(storeData.getConfigurations(), storeData.getDeletedEphemeralSSIDs()); return true; } @@ -1917,7 +1964,6 @@ public class WifiConfigManagerNew { Log.wtf(TAG, "XML serialization for store failed. Saved networks maybe lost!", e); return false; } - long writeTime = mClock.getElapsedSinceBootMillis() - writeStartTime; Log.d(TAG, "Writing to store completed in " + writeTime + " ms."); return true; diff --git a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java b/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java index fcbd0ba0f..a217de911 100644 --- a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java +++ b/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java @@ -43,7 +43,7 @@ import java.util.Set; * 4. /data/misc/wifi/PerProviderSubscription.conf * * The order of invocation of the public methods during migration is the following: - * 1. Check if legacy stores are present using {@link #isStoresPresent()}. + * 1. Check if legacy stores are present using {@link #areStoresPresent()}. * 2. Load all the store data using {@link #read()} * 3. Write the store data to the new store. * 4. Remove all the legacy stores using {@link #removeStores()} @@ -263,7 +263,7 @@ public class WifiConfigStoreLegacy { * * @return true if legacy store files are present, false otherwise. */ - public boolean isStoresPresent() { + public boolean areStoresPresent() { // We may have to keep the wpa_supplicant.conf file around. So, just use networkhistory.txt // as a check to see if we have not yet migrated or not. This should be the last file // that is deleted after migration. diff --git a/service/java/com/android/server/wifi/WifiConfigStoreNew.java b/service/java/com/android/server/wifi/WifiConfigStoreNew.java index 72f5d63ab..faf861bda 100644 --- a/service/java/com/android/server/wifi/WifiConfigStoreNew.java +++ b/service/java/com/android/server/wifi/WifiConfigStoreNew.java @@ -158,6 +158,16 @@ public class WifiConfigStoreNew { } /** + * API to check if any of the store files are present on the device. This can be used + * to detect if the device needs to perform data migration from legacy stores. + * + * @return true if any of the store file is present, false otherwise. + */ + public boolean areStoresPresent() { + return (mSharedStore.exists() || mUserStore.exists()); + } + + /** * API to write the provided store data to config stores. * The method writes the user specific configurations to user specific config store and the * shared configurations to shared config store. @@ -273,6 +283,15 @@ public class WifiConfigStoreNew { } /** + * Returns whether the store file already exists on disk or not. + * + * @return true if it exists, false otherwise. + */ + public boolean exists() { + return mAtomicFile.exists(); + } + + /** * Read the entire raw data from the store file and return in a byte array. * * @return raw data read from the file or null if the file is not found. |