summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2017-09-07 22:23:50 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-09-07 22:23:50 +0000
commitd0cafb20481fc76e546deb9d71626e79e320d440 (patch)
tree7c1142c3471b29922dd44dcddfdeca856993ece7
parentd63732781d42d4401dff33c241b261c68cdb85e4 (diff)
parenta83bd15861ae7175b1f62bc2dc8de63e0dbe808e (diff)
downloadandroid_frameworks_opt_net_wifi-d0cafb20481fc76e546deb9d71626e79e320d440.tar.gz
android_frameworks_opt_net_wifi-d0cafb20481fc76e546deb9d71626e79e320d440.tar.bz2
android_frameworks_opt_net_wifi-d0cafb20481fc76e546deb9d71626e79e320d440.zip
Merge "WifiConfigStore: Remove legacy modules" into oc-mr1-dev
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java50
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStoreLegacy.java354
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java9
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkHistory.java630
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java4
-rw-r--r--service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfigParser.java513
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java76
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java273
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/LegacyPasspointConfigParserTest.java204
9 files changed, 4 insertions, 2109 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 8180ab70b..75b39b261 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -47,7 +47,6 @@ 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.hotspot2.PasspointManager;
import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -248,7 +247,6 @@ public class WifiConfigManager {
private final TelephonyManager mTelephonyManager;
private final WifiKeyStore mWifiKeyStore;
private final WifiConfigStore mWifiConfigStore;
- private final WifiConfigStoreLegacy mWifiConfigStoreLegacy;
private final WifiPermissionsUtil mWifiPermissionsUtil;
private final WifiPermissionsWrapper mWifiPermissionsWrapper;
/**
@@ -342,7 +340,7 @@ public class WifiConfigManager {
WifiConfigManager(
Context context, Clock clock, UserManager userManager,
TelephonyManager telephonyManager, WifiKeyStore wifiKeyStore,
- WifiConfigStore wifiConfigStore, WifiConfigStoreLegacy wifiConfigStoreLegacy,
+ WifiConfigStore wifiConfigStore,
WifiPermissionsUtil wifiPermissionsUtil,
WifiPermissionsWrapper wifiPermissionsWrapper,
NetworkListStoreData networkListStoreData,
@@ -354,7 +352,6 @@ public class WifiConfigManager {
mTelephonyManager = telephonyManager;
mWifiKeyStore = wifiKeyStore;
mWifiConfigStore = wifiConfigStore;
- mWifiConfigStoreLegacy = wifiConfigStoreLegacy;
mWifiPermissionsUtil = wifiPermissionsUtil;
mWifiPermissionsWrapper = wifiPermissionsWrapper;
@@ -2697,46 +2694,6 @@ public class WifiConfigManager {
}
/**
- * Migrate data from legacy store files. The function performs the following operations:
- * 1. Check if the legacy store files are present and the new store files are absent on device.
- * 2. 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.
- */
- public boolean migrateFromLegacyStore() {
- if (!mWifiConfigStoreLegacy.areStoresPresent()) {
- Log.d(TAG, "Legacy store files not found. No migration needed!");
- return true;
- }
- if (mWifiConfigStore.areStoresPresent()) {
- Log.d(TAG, "New store files found. No migration needed!"
- + " Remove legacy store files");
- mWifiConfigStoreLegacy.removeStores();
- return true;
- }
- WifiConfigStoreDataLegacy storeData = mWifiConfigStoreLegacy.read();
- Log.d(TAG, "Reading from legacy store completed");
- loadInternalData(storeData.getConfigurations(), new ArrayList<WifiConfiguration>(),
- storeData.getDeletedEphemeralSSIDs());
-
- // Setup user store for the current user in case it have not setup yet, so that data
- // owned by the current user will be backed to the user store.
- if (mDeferredUserUnlockRead) {
- mWifiConfigStore.setUserStore(WifiConfigStore.createUserFile(mCurrentUserId));
- mDeferredUserUnlockRead = false;
- }
-
- if (!saveToStore(true)) {
- return false;
- }
- 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.
*
@@ -2750,10 +2707,7 @@ public class WifiConfigManager {
public boolean loadFromStore() {
if (!mWifiConfigStore.areStoresPresent()) {
Log.d(TAG, "New store files not found. No saved networks loaded!");
- if (!mWifiConfigStoreLegacy.areStoresPresent()) {
- // No legacy store files either, so reset the pending store read flag.
- mPendingStoreRead = false;
- }
+ mPendingStoreRead = false;
return true;
}
// If the user unlock comes in before we load from store, which means the user store have
diff --git a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java b/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java
deleted file mode 100644
index 39e48a5cb..000000000
--- a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.net.IpConfiguration;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.os.Environment;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.server.net.IpConfigStore;
-import com.android.server.wifi.hotspot2.LegacyPasspointConfig;
-import com.android.server.wifi.hotspot2.LegacyPasspointConfigParser;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This class provides the API's to load network configurations from legacy store
- * mechanism (Pre O release).
- * This class loads network configurations from:
- * 1. /data/misc/wifi/networkHistory.txt
- * 2. /data/misc/wifi/wpa_supplicant.conf
- * 3. /data/misc/wifi/ipconfig.txt
- * 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 #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()}
- *
- * NOTE: This class should only be used from WifiConfigManager and is not thread-safe!
- *
- * TODO(b/31065385): Passpoint config store data migration & deletion.
- */
-public class WifiConfigStoreLegacy {
- /**
- * Log tag.
- */
- private static final String TAG = "WifiConfigStoreLegacy";
- /**
- * NetworkHistory config store file path.
- */
- private static final File NETWORK_HISTORY_FILE =
- new File(WifiNetworkHistory.NETWORK_HISTORY_CONFIG_FILE);
- /**
- * Passpoint config store file path.
- */
- private static final File PPS_FILE =
- new File(Environment.getDataMiscDirectory(), "wifi/PerProviderSubscription.conf");
- /**
- * IpConfig config store file path.
- */
- private static final File IP_CONFIG_FILE =
- new File(Environment.getDataMiscDirectory(), "wifi/ipconfig.txt");
- /**
- * List of external dependencies for WifiConfigManager.
- */
- private final WifiNetworkHistory mWifiNetworkHistory;
- private final WifiNative mWifiNative;
- private final IpConfigStore mIpconfigStore;
-
- private final LegacyPasspointConfigParser mPasspointConfigParser;
-
- WifiConfigStoreLegacy(WifiNetworkHistory wifiNetworkHistory,
- WifiNative wifiNative, IpConfigStore ipConfigStore,
- LegacyPasspointConfigParser passpointConfigParser) {
- mWifiNetworkHistory = wifiNetworkHistory;
- mWifiNative = wifiNative;
- mIpconfigStore = ipConfigStore;
- mPasspointConfigParser = passpointConfigParser;
- }
-
- /**
- * Helper function to lookup the WifiConfiguration object from configKey to WifiConfiguration
- * object map using the hashcode of the configKey.
- *
- * @param configurationMap Map of configKey to WifiConfiguration object.
- * @param hashCode hash code of the configKey to match.
- * @return
- */
- private static WifiConfiguration lookupWifiConfigurationUsingConfigKeyHash(
- Map<String, WifiConfiguration> configurationMap, int hashCode) {
- for (Map.Entry<String, WifiConfiguration> entry : configurationMap.entrySet()) {
- if (entry.getKey().hashCode() == hashCode) {
- return entry.getValue();
- }
- }
- return null;
- }
-
- /**
- * Helper function to load {@link IpConfiguration} data from the ip config store file and
- * populate the provided configuration map.
- *
- * @param configurationMap Map of configKey to WifiConfiguration object.
- */
- private void loadFromIpConfigStore(Map<String, WifiConfiguration> configurationMap) {
- // This is a map of the hash code of the network's configKey to the corresponding
- // IpConfiguration.
- SparseArray<IpConfiguration> ipConfigurations =
- mIpconfigStore.readIpAndProxyConfigurations(IP_CONFIG_FILE.getAbsolutePath());
- if (ipConfigurations == null || ipConfigurations.size() == 0) {
- Log.w(TAG, "No ip configurations found in ipconfig store");
- return;
- }
- for (int i = 0; i < ipConfigurations.size(); i++) {
- int id = ipConfigurations.keyAt(i);
- WifiConfiguration config =
- lookupWifiConfigurationUsingConfigKeyHash(configurationMap, id);
- // This is the only place the map is looked up through a (dangerous) hash-value!
- if (config == null || config.ephemeral) {
- Log.w(TAG, "configuration found for missing network, nid=" + id
- + ", ignored, networks.size=" + Integer.toString(ipConfigurations.size()));
- } else {
- config.setIpConfiguration(ipConfigurations.valueAt(i));
- }
- }
- }
-
- /**
- * Helper function to load {@link WifiConfiguration} data from networkHistory file and populate
- * the provided configuration map and deleted ephemeral ssid list.
- *
- * @param configurationMap Map of configKey to WifiConfiguration object.
- * @param deletedEphemeralSSIDs Map of configKey to WifiConfiguration object.
- */
- private void loadFromNetworkHistory(
- Map<String, WifiConfiguration> configurationMap, Set<String> deletedEphemeralSSIDs) {
- // TODO: Need to revisit the scan detail cache persistance. We're not doing it in the new
- // config store, so ignore it here as well.
- Map<Integer, ScanDetailCache> scanDetailCaches = new HashMap<>();
- mWifiNetworkHistory.readNetworkHistory(
- configurationMap, scanDetailCaches, deletedEphemeralSSIDs);
- }
-
- /**
- * Helper function to load {@link WifiConfiguration} data from wpa_supplicant and populate
- * the provided configuration map and network extras.
- *
- * This method needs to manually parse the wpa_supplicant.conf file to retrieve some of the
- * password fields like psk, wep_keys. password, etc.
- *
- * @param configurationMap Map of configKey to WifiConfiguration object.
- * @param networkExtras Map of network extras parsed from wpa_supplicant.
- */
- private void loadFromWpaSupplicant(
- Map<String, WifiConfiguration> configurationMap,
- SparseArray<Map<String, String>> networkExtras) {
- if (!mWifiNative.migrateNetworksFromSupplicant(configurationMap, networkExtras)) {
- Log.wtf(TAG, "Failed to load wifi configurations from wpa_supplicant");
- return;
- }
- if (configurationMap.isEmpty()) {
- Log.w(TAG, "No wifi configurations found in wpa_supplicant");
- return;
- }
- }
-
- /**
- * Helper function to update {@link WifiConfiguration} that represents a Passpoint
- * configuration.
- *
- * This method will manually parse PerProviderSubscription.conf file to retrieve missing
- * fields: provider friendly name, roaming consortium OIs, realm, IMSI.
- *
- * @param configurationMap Map of configKey to WifiConfiguration object.
- * @param networkExtras Map of network extras parsed from wpa_supplicant.
- */
- private void loadFromPasspointConfigStore(
- Map<String, WifiConfiguration> configurationMap,
- SparseArray<Map<String, String>> networkExtras) {
- Map<String, LegacyPasspointConfig> passpointConfigMap = null;
- try {
- passpointConfigMap = mPasspointConfigParser.parseConfig(PPS_FILE.getAbsolutePath());
- } catch (IOException e) {
- Log.w(TAG, "Failed to read/parse Passpoint config file: " + e.getMessage());
- }
-
- List<String> entriesToBeRemoved = new ArrayList<>();
- for (Map.Entry<String, WifiConfiguration> entry : configurationMap.entrySet()) {
- WifiConfiguration wifiConfig = entry.getValue();
- // Ignore non-Enterprise network since enterprise configuration is required for
- // Passpoint.
- if (wifiConfig.enterpriseConfig == null || wifiConfig.enterpriseConfig.getEapMethod()
- == WifiEnterpriseConfig.Eap.NONE) {
- continue;
- }
- // Ignore configuration without FQDN.
- Map<String, String> extras = networkExtras.get(wifiConfig.networkId);
- if (extras == null || !extras.containsKey(SupplicantStaNetworkHal.ID_STRING_KEY_FQDN)) {
- continue;
- }
- String fqdn = networkExtras.get(wifiConfig.networkId).get(
- SupplicantStaNetworkHal.ID_STRING_KEY_FQDN);
-
- // Remove the configuration if failed to find the matching configuration in the
- // Passpoint configuration file.
- if (passpointConfigMap == null || !passpointConfigMap.containsKey(fqdn)) {
- entriesToBeRemoved.add(entry.getKey());
- continue;
- }
-
- // Update the missing Passpoint configuration fields to this WifiConfiguration.
- LegacyPasspointConfig passpointConfig = passpointConfigMap.get(fqdn);
- wifiConfig.isLegacyPasspointConfig = true;
- wifiConfig.FQDN = fqdn;
- wifiConfig.providerFriendlyName = passpointConfig.mFriendlyName;
- if (passpointConfig.mRoamingConsortiumOis != null) {
- wifiConfig.roamingConsortiumIds = Arrays.copyOf(
- passpointConfig.mRoamingConsortiumOis,
- passpointConfig.mRoamingConsortiumOis.length);
- }
- if (passpointConfig.mImsi != null) {
- wifiConfig.enterpriseConfig.setPlmn(passpointConfig.mImsi);
- }
- if (passpointConfig.mRealm != null) {
- wifiConfig.enterpriseConfig.setRealm(passpointConfig.mRealm);
- }
- }
-
- // Remove any incomplete Passpoint configurations. Should never happen, in case it does
- // remove them to avoid maintaining any invalid Passpoint configurations.
- for (String key : entriesToBeRemoved) {
- Log.w(TAG, "Remove incomplete Passpoint configuration: " + key);
- configurationMap.remove(key);
- }
- }
-
- /**
- * Helper function to load from the different legacy stores:
- * 1. Read the network configurations from wpa_supplicant using {@link WifiNative}.
- * 2. Read the network configurations from networkHistory.txt using {@link WifiNetworkHistory}.
- * 3. Read the Ip configurations from ipconfig.txt using {@link IpConfigStore}.
- * 4. Read all the passpoint info from PerProviderSubscription.conf using
- * {@link LegacyPasspointConfigParser}.
- */
- public WifiConfigStoreDataLegacy read() {
- final Map<String, WifiConfiguration> configurationMap = new HashMap<>();
- final SparseArray<Map<String, String>> networkExtras = new SparseArray<>();
- final Set<String> deletedEphemeralSSIDs = new HashSet<>();
-
- loadFromWpaSupplicant(configurationMap, networkExtras);
- loadFromNetworkHistory(configurationMap, deletedEphemeralSSIDs);
- loadFromIpConfigStore(configurationMap);
- loadFromPasspointConfigStore(configurationMap, networkExtras);
-
- // Now create config store data instance to be returned.
- return new WifiConfigStoreDataLegacy(
- new ArrayList<>(configurationMap.values()), deletedEphemeralSSIDs);
- }
-
- /**
- * Function to check if the legacy store files are present and hence load from those stores and
- * then delete them.
- *
- * @return true if legacy store files are present, false otherwise.
- */
- 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.
- File file = new File(WifiNetworkHistory.NETWORK_HISTORY_CONFIG_FILE);
- return file.exists();
- }
-
- /**
- * Method to remove all the legacy store files. This should only be invoked once all
- * the data has been migrated to the new store file.
- * 1. Removes all networks from wpa_supplicant and saves it to wpa_supplicant.conf
- * 2. Deletes ipconfig.txt
- * 3. Deletes networkHistory.txt
- *
- * @return true if all the store files were deleted successfully, false otherwise.
- */
- public boolean removeStores() {
- // TODO(b/29352330): Delete wpa_supplicant.conf file instead.
- // First remove all networks from wpa_supplicant and save configuration.
- if (!mWifiNative.removeAllNetworks()) {
- Log.e(TAG, "Removing networks from wpa_supplicant failed");
- }
-
- // Now remove the ipconfig.txt file.
- if (!IP_CONFIG_FILE.delete()) {
- Log.e(TAG, "Removing ipconfig.txt failed");
- }
-
- // Now finally remove network history.txt
- if (!NETWORK_HISTORY_FILE.delete()) {
- Log.e(TAG, "Removing networkHistory.txt failed");
- }
-
- if (!PPS_FILE.delete()) {
- Log.e(TAG, "Removing PerProviderSubscription.conf failed");
- }
-
- Log.i(TAG, "All legacy stores removed!");
- return true;
- }
-
- /**
- * Interface used to set a masked value in the provided configuration. The masked value is
- * retrieved by parsing the wpa_supplicant.conf file.
- */
- private interface MaskedWpaSupplicantFieldSetter {
- void setValue(WifiConfiguration config, String value);
- }
-
- /**
- * Class used to encapsulate all the store data retrieved from the legacy (Pre O) store files.
- */
- public static class WifiConfigStoreDataLegacy {
- private List<WifiConfiguration> mConfigurations;
- private Set<String> mDeletedEphemeralSSIDs;
- // private List<HomeSP> mHomeSps;
-
- WifiConfigStoreDataLegacy(List<WifiConfiguration> configurations,
- Set<String> deletedEphemeralSSIDs) {
- mConfigurations = configurations;
- mDeletedEphemeralSSIDs = deletedEphemeralSSIDs;
- }
-
- public List<WifiConfiguration> getConfigurations() {
- return mConfigurations;
- }
-
- public Set<String> getDeletedEphemeralSSIDs() {
- return mDeletedEphemeralSSIDs;
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 26d702477..734c28d19 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -45,7 +45,6 @@ import com.android.server.am.BatteryStatsService;
import com.android.server.net.DelayedDiskWrite;
import com.android.server.net.IpConfigStore;
import com.android.server.wifi.aware.WifiAwareMetrics;
-import com.android.server.wifi.hotspot2.LegacyPasspointConfigParser;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointNetworkEvaluator;
import com.android.server.wifi.hotspot2.PasspointObjectFactory;
@@ -101,9 +100,7 @@ public class WifiInjector {
private final WifiMulticastLockManager mWifiMulticastLockManager;
private final WifiConfigStore mWifiConfigStore;
private final WifiKeyStore mWifiKeyStore;
- private final WifiNetworkHistory mWifiNetworkHistory;
private final IpConfigStore mIpConfigStore;
- private final WifiConfigStoreLegacy mWifiConfigStoreLegacy;
private final WifiConfigManager mWifiConfigManager;
private final WifiConnectivityHelper mWifiConnectivityHelper;
private final LocalLog mConnectivityLocalLog;
@@ -195,15 +192,11 @@ public class WifiInjector {
WifiConfigStore.createSharedFile());
// Legacy config store
DelayedDiskWrite writer = new DelayedDiskWrite();
- mWifiNetworkHistory = new WifiNetworkHistory(mContext, writer);
mIpConfigStore = new IpConfigStore(writer);
- mWifiConfigStoreLegacy = new WifiConfigStoreLegacy(
- mWifiNetworkHistory, mWifiNative, mIpConfigStore,
- new LegacyPasspointConfigParser());
// Config Manager
mWifiConfigManager = new WifiConfigManager(mContext, mClock,
UserManager.get(mContext), TelephonyManager.from(mContext),
- mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy, mWifiPermissionsUtil,
+ mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
mWifiPermissionsWrapper, new NetworkListStoreData(),
new DeletedEphemeralSsidsStoreData());
mWifiMetrics.setWifiConfigManager(mWifiConfigManager);
diff --git a/service/java/com/android/server/wifi/WifiNetworkHistory.java b/service/java/com/android/server/wifi/WifiNetworkHistory.java
deleted file mode 100644
index 282f6057d..000000000
--- a/service/java/com/android/server/wifi/WifiNetworkHistory.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.content.Context;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
-import android.net.wifi.WifiSsid;
-import android.os.Environment;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.server.net.DelayedDiskWrite;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Provides an API to read and write the network history from WifiConfigurations to file
- * This is largely separate and extra to the supplicant config file.
- */
-public class WifiNetworkHistory {
- public static final String TAG = "WifiNetworkHistory";
- private static final boolean DBG = true;
- private static final boolean VDBG = true;
- static final String NETWORK_HISTORY_CONFIG_FILE = Environment.getDataDirectory()
- + "/misc/wifi/networkHistory.txt";
- /* Network History Keys */
- private static final String SSID_KEY = "SSID";
- static final String CONFIG_KEY = "CONFIG";
- private static final String CONFIG_BSSID_KEY = "CONFIG_BSSID";
- private static final String CHOICE_KEY = "CHOICE";
- private static final String CHOICE_TIME_KEY = "CHOICE_TIME";
- private static final String LINK_KEY = "LINK";
- private static final String BSSID_KEY = "BSSID";
- private static final String BSSID_KEY_END = "/BSSID";
- private static final String RSSI_KEY = "RSSI";
- private static final String FREQ_KEY = "FREQ";
- private static final String DATE_KEY = "DATE";
- private static final String MILLI_KEY = "MILLI";
- private static final String NETWORK_ID_KEY = "ID";
- private static final String PRIORITY_KEY = "PRIORITY";
- private static final String DEFAULT_GW_KEY = "DEFAULT_GW";
- private static final String AUTH_KEY = "AUTH";
- private static final String BSSID_STATUS_KEY = "BSSID_STATUS";
- private static final String SELF_ADDED_KEY = "SELF_ADDED";
- private static final String DID_SELF_ADD_KEY = "DID_SELF_ADD";
- private static final String PEER_CONFIGURATION_KEY = "PEER_CONFIGURATION";
- static final String CREATOR_UID_KEY = "CREATOR_UID_KEY";
- private static final String CONNECT_UID_KEY = "CONNECT_UID_KEY";
- private static final String UPDATE_UID_KEY = "UPDATE_UID";
- private static final String FQDN_KEY = "FQDN";
- private static final String SCORER_OVERRIDE_KEY = "SCORER_OVERRIDE";
- private static final String SCORER_OVERRIDE_AND_SWITCH_KEY = "SCORER_OVERRIDE_AND_SWITCH";
- private static final String VALIDATED_INTERNET_ACCESS_KEY = "VALIDATED_INTERNET_ACCESS";
- private static final String NO_INTERNET_ACCESS_REPORTS_KEY = "NO_INTERNET_ACCESS_REPORTS";
- private static final String NO_INTERNET_ACCESS_EXPECTED_KEY = "NO_INTERNET_ACCESS_EXPECTED";
- private static final String EPHEMERAL_KEY = "EPHEMERAL";
- private static final String USE_EXTERNAL_SCORES_KEY = "USE_EXTERNAL_SCORES";
- private static final String METERED_HINT_KEY = "METERED_HINT";
- private static final String METERED_OVERRIDE_KEY = "METERED_OVERRIDE";
- private static final String NUM_ASSOCIATION_KEY = "NUM_ASSOCIATION";
- private static final String DELETED_EPHEMERAL_KEY = "DELETED_EPHEMERAL";
- private static final String CREATOR_NAME_KEY = "CREATOR_NAME";
- private static final String UPDATE_NAME_KEY = "UPDATE_NAME";
- private static final String USER_APPROVED_KEY = "USER_APPROVED";
- private static final String CREATION_TIME_KEY = "CREATION_TIME";
- private static final String UPDATE_TIME_KEY = "UPDATE_TIME";
- static final String SHARED_KEY = "SHARED";
- private static final String NETWORK_SELECTION_STATUS_KEY = "NETWORK_SELECTION_STATUS";
- private static final String NETWORK_SELECTION_DISABLE_REASON_KEY =
- "NETWORK_SELECTION_DISABLE_REASON";
- private static final String HAS_EVER_CONNECTED_KEY = "HAS_EVER_CONNECTED";
-
- private static final String SEPARATOR = ": ";
- private static final String NL = "\n";
-
- protected final DelayedDiskWrite mWriter;
- Context mContext;
- /*
- * Lost config list, whenever we read a config from networkHistory.txt that was not in
- * wpa_supplicant.conf
- */
- HashSet<String> mLostConfigsDbg = new HashSet<String>();
-
- public WifiNetworkHistory(Context c, DelayedDiskWrite writer) {
- mContext = c;
- mWriter = writer;
- }
-
- /**
- * Write network history to file, for configured networks
- *
- * @param networks List of ConfiguredNetworks to write to NetworkHistory
- */
- public void writeKnownNetworkHistory(final List<WifiConfiguration> networks,
- final ConcurrentHashMap<Integer, ScanDetailCache> scanDetailCaches,
- final Set<String> deletedEphemeralSSIDs) {
-
- /* Make a copy */
- //final List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-
- //for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) {
- // networks.add(new WifiConfiguration(config));
- //}
-
- mWriter.write(NETWORK_HISTORY_CONFIG_FILE, new DelayedDiskWrite.Writer() {
- public void onWriteCalled(DataOutputStream out) throws IOException {
- for (WifiConfiguration config : networks) {
- //loge("onWriteCalled write SSID: " + config.SSID);
- /* if (config.getLinkProperties() != null)
- loge(" lp " + config.getLinkProperties().toString());
- else
- loge("attempt config w/o lp");
- */
- NetworkSelectionStatus status = config.getNetworkSelectionStatus();
- if (VDBG) {
- int numlink = 0;
- if (config.linkedConfigurations != null) {
- numlink = config.linkedConfigurations.size();
- }
- String disableTime;
- if (config.getNetworkSelectionStatus().isNetworkEnabled()) {
- disableTime = "";
- } else {
- disableTime = "Disable time: " + DateFormat.getInstance().format(
- config.getNetworkSelectionStatus().getDisableTime());
- }
- logd("saving network history: " + config.configKey() + " gw: "
- + config.defaultGwMacAddress + " Network Selection-status: "
- + status.getNetworkStatusString()
- + disableTime + " ephemeral=" + config.ephemeral
- + " choice:" + status.getConnectChoice()
- + " link:" + numlink
- + " status:" + config.status
- + " nid:" + config.networkId
- + " hasEverConnected: " + status.getHasEverConnected());
- }
-
- if (!isValid(config)) {
- continue;
- }
-
- if (config.SSID == null) {
- if (VDBG) {
- logv("writeKnownNetworkHistory trying to write config with null SSID");
- }
- continue;
- }
- if (VDBG) {
- logv("writeKnownNetworkHistory write config " + config.configKey());
- }
- out.writeUTF(CONFIG_KEY + SEPARATOR + config.configKey() + NL);
-
- if (config.SSID != null) {
- out.writeUTF(SSID_KEY + SEPARATOR + config.SSID + NL);
- }
- if (config.BSSID != null) {
- out.writeUTF(CONFIG_BSSID_KEY + SEPARATOR + config.BSSID + NL);
- } else {
- out.writeUTF(CONFIG_BSSID_KEY + SEPARATOR + "null" + NL);
- }
- if (config.FQDN != null) {
- out.writeUTF(FQDN_KEY + SEPARATOR + config.FQDN + NL);
- }
-
- out.writeUTF(PRIORITY_KEY + SEPARATOR + Integer.toString(config.priority) + NL);
- out.writeUTF(NETWORK_ID_KEY + SEPARATOR
- + Integer.toString(config.networkId) + NL);
- out.writeUTF(SELF_ADDED_KEY + SEPARATOR
- + Boolean.toString(config.selfAdded) + NL);
- out.writeUTF(DID_SELF_ADD_KEY + SEPARATOR
- + Boolean.toString(config.didSelfAdd) + NL);
- out.writeUTF(NO_INTERNET_ACCESS_REPORTS_KEY + SEPARATOR
- + Integer.toString(config.numNoInternetAccessReports) + NL);
- out.writeUTF(VALIDATED_INTERNET_ACCESS_KEY + SEPARATOR
- + Boolean.toString(config.validatedInternetAccess) + NL);
- out.writeUTF(NO_INTERNET_ACCESS_EXPECTED_KEY + SEPARATOR +
- Boolean.toString(config.noInternetAccessExpected) + NL);
- out.writeUTF(EPHEMERAL_KEY + SEPARATOR
- + Boolean.toString(config.ephemeral) + NL);
- out.writeUTF(METERED_HINT_KEY + SEPARATOR
- + Boolean.toString(config.meteredHint) + NL);
- out.writeUTF(METERED_OVERRIDE_KEY + SEPARATOR
- + Integer.toString(config.meteredOverride) + NL);
- out.writeUTF(USE_EXTERNAL_SCORES_KEY + SEPARATOR
- + Boolean.toString(config.useExternalScores) + NL);
- if (config.creationTime != null) {
- out.writeUTF(CREATION_TIME_KEY + SEPARATOR + config.creationTime + NL);
- }
- if (config.updateTime != null) {
- out.writeUTF(UPDATE_TIME_KEY + SEPARATOR + config.updateTime + NL);
- }
- if (config.peerWifiConfiguration != null) {
- out.writeUTF(PEER_CONFIGURATION_KEY + SEPARATOR
- + config.peerWifiConfiguration + NL);
- }
- out.writeUTF(SCORER_OVERRIDE_KEY + SEPARATOR
- + Integer.toString(config.numScorerOverride) + NL);
- out.writeUTF(SCORER_OVERRIDE_AND_SWITCH_KEY + SEPARATOR
- + Integer.toString(config.numScorerOverrideAndSwitchedNetwork) + NL);
- out.writeUTF(NUM_ASSOCIATION_KEY + SEPARATOR
- + Integer.toString(config.numAssociation) + NL);
- out.writeUTF(CREATOR_UID_KEY + SEPARATOR
- + Integer.toString(config.creatorUid) + NL);
- out.writeUTF(CONNECT_UID_KEY + SEPARATOR
- + Integer.toString(config.lastConnectUid) + NL);
- out.writeUTF(UPDATE_UID_KEY + SEPARATOR
- + Integer.toString(config.lastUpdateUid) + NL);
- out.writeUTF(CREATOR_NAME_KEY + SEPARATOR
- + config.creatorName + NL);
- out.writeUTF(UPDATE_NAME_KEY + SEPARATOR
- + config.lastUpdateName + NL);
- out.writeUTF(USER_APPROVED_KEY + SEPARATOR
- + Integer.toString(config.userApproved) + NL);
- out.writeUTF(SHARED_KEY + SEPARATOR + Boolean.toString(config.shared) + NL);
- String allowedKeyManagementString =
- makeString(config.allowedKeyManagement,
- WifiConfiguration.KeyMgmt.strings);
- out.writeUTF(AUTH_KEY + SEPARATOR
- + allowedKeyManagementString + NL);
- out.writeUTF(NETWORK_SELECTION_STATUS_KEY + SEPARATOR
- + status.getNetworkSelectionStatus() + NL);
- out.writeUTF(NETWORK_SELECTION_DISABLE_REASON_KEY + SEPARATOR
- + status.getNetworkSelectionDisableReason() + NL);
-
- if (status.getConnectChoice() != null) {
- out.writeUTF(CHOICE_KEY + SEPARATOR + status.getConnectChoice() + NL);
- out.writeUTF(CHOICE_TIME_KEY + SEPARATOR
- + status.getConnectChoiceTimestamp() + NL);
- }
-
- if (config.linkedConfigurations != null) {
- log("writeKnownNetworkHistory write linked "
- + config.linkedConfigurations.size());
-
- for (String key : config.linkedConfigurations.keySet()) {
- out.writeUTF(LINK_KEY + SEPARATOR + key + NL);
- }
- }
-
- String macAddress = config.defaultGwMacAddress;
- if (macAddress != null) {
- out.writeUTF(DEFAULT_GW_KEY + SEPARATOR + macAddress + NL);
- }
-
- if (getScanDetailCache(config, scanDetailCaches) != null) {
- for (ScanDetail scanDetail : getScanDetailCache(config,
- scanDetailCaches).values()) {
- ScanResult result = scanDetail.getScanResult();
- out.writeUTF(BSSID_KEY + SEPARATOR
- + result.BSSID + NL);
- out.writeUTF(FREQ_KEY + SEPARATOR
- + Integer.toString(result.frequency) + NL);
-
- out.writeUTF(RSSI_KEY + SEPARATOR
- + Integer.toString(result.level) + NL);
-
- out.writeUTF(BSSID_KEY_END + NL);
- }
- }
- out.writeUTF(HAS_EVER_CONNECTED_KEY + SEPARATOR
- + Boolean.toString(status.getHasEverConnected()) + NL);
- out.writeUTF(NL);
- // Add extra blank lines for clarity
- out.writeUTF(NL);
- out.writeUTF(NL);
- }
- if (deletedEphemeralSSIDs != null && deletedEphemeralSSIDs.size() > 0) {
- for (String ssid : deletedEphemeralSSIDs) {
- out.writeUTF(DELETED_EPHEMERAL_KEY);
- out.writeUTF(ssid);
- out.writeUTF(NL);
- }
- }
- }
- });
- }
-
- /**
- * Adds information stored in networkHistory.txt to the given configs. The configs are provided
- * as a mapping from configKey to WifiConfiguration, because the WifiConfigurations themselves
- * do not contain sufficient information to compute their configKeys until after the information
- * that is stored in networkHistory.txt has been added to them.
- *
- * @param configs mapping from configKey to a WifiConfiguration that contains the information
- * information read from wpa_supplicant.conf
- */
- public void readNetworkHistory(Map<String, WifiConfiguration> configs,
- Map<Integer, ScanDetailCache> scanDetailCaches,
- Set<String> deletedEphemeralSSIDs) {
-
- try (DataInputStream in =
- new DataInputStream(new BufferedInputStream(
- new FileInputStream(NETWORK_HISTORY_CONFIG_FILE)))) {
-
- String bssid = null;
- String ssid = null;
-
- int freq = 0;
- int status = 0;
- long seen = 0;
- int rssi = WifiConfiguration.INVALID_RSSI;
- String caps = null;
-
- WifiConfiguration config = null;
- while (true) {
- String line = in.readUTF();
- if (line == null) {
- break;
- }
- int colon = line.indexOf(':');
- if (colon < 0) {
- continue;
- }
-
- String key = line.substring(0, colon).trim();
- String value = line.substring(colon + 1).trim();
-
- if (key.equals(CONFIG_KEY)) {
- config = configs.get(value);
-
- // skip reading that configuration data
- // since we don't have a corresponding network ID
- if (config == null) {
- Log.e(TAG, "readNetworkHistory didnt find netid for hash="
- + Integer.toString(value.hashCode())
- + " key: " + value);
- mLostConfigsDbg.add(value);
- continue;
- } else {
- // After an upgrade count old connections as owned by system
- if (config.creatorName == null || config.lastUpdateName == null) {
- config.creatorName =
- mContext.getPackageManager().getNameForUid(Process.SYSTEM_UID);
- config.lastUpdateName = config.creatorName;
-
- if (DBG) {
- Log.w(TAG, "Upgrading network " + config.networkId
- + " to " + config.creatorName);
- }
- }
- }
- } else if (config != null) {
- NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
- switch (key) {
- case SSID_KEY:
- if (config.isPasspoint()) {
- break;
- }
- ssid = value;
- if (config.SSID != null && !config.SSID.equals(ssid)) {
- loge("Error parsing network history file, mismatched SSIDs");
- config = null; //error
- ssid = null;
- } else {
- config.SSID = ssid;
- }
- break;
- case CONFIG_BSSID_KEY:
- config.BSSID = value.equals("null") ? null : value;
- break;
- case FQDN_KEY:
- // Check for literal 'null' to be backwards compatible.
- config.FQDN = value.equals("null") ? null : value;
- break;
- case DEFAULT_GW_KEY:
- config.defaultGwMacAddress = value;
- break;
- case SELF_ADDED_KEY:
- config.selfAdded = Boolean.parseBoolean(value);
- break;
- case DID_SELF_ADD_KEY:
- config.didSelfAdd = Boolean.parseBoolean(value);
- break;
- case NO_INTERNET_ACCESS_REPORTS_KEY:
- config.numNoInternetAccessReports = Integer.parseInt(value);
- break;
- case VALIDATED_INTERNET_ACCESS_KEY:
- config.validatedInternetAccess = Boolean.parseBoolean(value);
- break;
- case NO_INTERNET_ACCESS_EXPECTED_KEY:
- config.noInternetAccessExpected = Boolean.parseBoolean(value);
- break;
- case CREATION_TIME_KEY:
- config.creationTime = value;
- break;
- case UPDATE_TIME_KEY:
- config.updateTime = value;
- break;
- case EPHEMERAL_KEY:
- config.ephemeral = Boolean.parseBoolean(value);
- break;
- case METERED_HINT_KEY:
- config.meteredHint = Boolean.parseBoolean(value);
- break;
- case METERED_OVERRIDE_KEY:
- config.meteredOverride = Integer.parseInt(value);
- break;
- case USE_EXTERNAL_SCORES_KEY:
- config.useExternalScores = Boolean.parseBoolean(value);
- break;
- case CREATOR_UID_KEY:
- config.creatorUid = Integer.parseInt(value);
- break;
- case SCORER_OVERRIDE_KEY:
- config.numScorerOverride = Integer.parseInt(value);
- break;
- case SCORER_OVERRIDE_AND_SWITCH_KEY:
- config.numScorerOverrideAndSwitchedNetwork = Integer.parseInt(value);
- break;
- case NUM_ASSOCIATION_KEY:
- config.numAssociation = Integer.parseInt(value);
- break;
- case CONNECT_UID_KEY:
- config.lastConnectUid = Integer.parseInt(value);
- break;
- case UPDATE_UID_KEY:
- config.lastUpdateUid = Integer.parseInt(value);
- break;
- case PEER_CONFIGURATION_KEY:
- config.peerWifiConfiguration = value;
- break;
- case NETWORK_SELECTION_STATUS_KEY:
- int networkStatusValue = Integer.parseInt(value);
- // Reset temporarily disabled network status
- if (networkStatusValue ==
- NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
- networkStatusValue =
- NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
- }
- networkStatus.setNetworkSelectionStatus(networkStatusValue);
- break;
- case NETWORK_SELECTION_DISABLE_REASON_KEY:
- networkStatus.setNetworkSelectionDisableReason(Integer.parseInt(value));
- break;
- case CHOICE_KEY:
- networkStatus.setConnectChoice(value);
- break;
- case CHOICE_TIME_KEY:
- networkStatus.setConnectChoiceTimestamp(Long.parseLong(value));
- break;
- case LINK_KEY:
- if (config.linkedConfigurations == null) {
- config.linkedConfigurations = new HashMap<>();
- } else {
- config.linkedConfigurations.put(value, -1);
- }
- break;
- case BSSID_KEY:
- status = 0;
- ssid = null;
- bssid = null;
- freq = 0;
- seen = 0;
- rssi = WifiConfiguration.INVALID_RSSI;
- caps = "";
- break;
- case RSSI_KEY:
- rssi = Integer.parseInt(value);
- break;
- case FREQ_KEY:
- freq = Integer.parseInt(value);
- break;
- case DATE_KEY:
- /*
- * when reading the configuration from file we don't update the date
- * so as to avoid reading back stale or non-sensical data that would
- * depend on network time.
- * The date of a WifiConfiguration should only come from actual scan
- * result.
- *
- String s = key.replace(FREQ_KEY, "");
- seen = Integer.getInteger(s);
- */
- break;
- case BSSID_KEY_END:
- if ((bssid != null) && (ssid != null)) {
- if (getScanDetailCache(config, scanDetailCaches) != null) {
- WifiSsid wssid = WifiSsid.createFromAsciiEncoded(ssid);
- ScanDetail scanDetail = new ScanDetail(wssid, bssid,
- caps, rssi, freq, (long) 0, seen);
- getScanDetailCache(config, scanDetailCaches).put(scanDetail);
- }
- }
- break;
- case DELETED_EPHEMERAL_KEY:
- if (!TextUtils.isEmpty(value)) {
- deletedEphemeralSSIDs.add(value);
- }
- break;
- case CREATOR_NAME_KEY:
- config.creatorName = value;
- break;
- case UPDATE_NAME_KEY:
- config.lastUpdateName = value;
- break;
- case USER_APPROVED_KEY:
- config.userApproved = Integer.parseInt(value);
- break;
- case SHARED_KEY:
- config.shared = Boolean.parseBoolean(value);
- break;
- case HAS_EVER_CONNECTED_KEY:
- networkStatus.setHasEverConnected(Boolean.parseBoolean(value));
- break;
- }
- }
- }
- } catch (EOFException e) {
- // do nothing
- } catch (FileNotFoundException e) {
- Log.i(TAG, "readNetworkHistory: no config file, " + e);
- } catch (NumberFormatException e) {
- Log.e(TAG, "readNetworkHistory: failed to parse, " + e, e);
- } catch (IOException e) {
- Log.e(TAG, "readNetworkHistory: failed to read, " + e, e);
- }
- }
-
- /**
- * Ported this out of WifiServiceImpl, I have no idea what it's doing
- * <TODO> figure out what/why this is doing
- * <TODO> Port it into WifiConfiguration, then remove all the silly business from ServiceImpl
- */
- public boolean isValid(WifiConfiguration config) {
- if (config.allowedKeyManagement == null) {
- return false;
- }
- if (config.allowedKeyManagement.cardinality() > 1) {
- if (config.allowedKeyManagement.cardinality() != 2) {
- return false;
- }
- if (!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
- return false;
- }
- if ((!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X))
- && (!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK))) {
- return false;
- }
- }
- return true;
- }
-
- private static String makeString(BitSet set, String[] strings) {
- StringBuffer buf = new StringBuffer();
- int nextSetBit = -1;
-
- /* Make sure all set bits are in [0, strings.length) to avoid
- * going out of bounds on strings. (Shouldn't happen, but...) */
- set = set.get(0, strings.length);
-
- while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
- buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
- }
-
- // remove trailing space
- if (set.cardinality() > 0) {
- buf.setLength(buf.length() - 1);
- }
-
- return buf.toString();
- }
-
- protected void logv(String s) {
- Log.v(TAG, s);
- }
- protected void logd(String s) {
- Log.d(TAG, s);
- }
- protected void log(String s) {
- Log.d(TAG, s);
- }
- protected void loge(String s) {
- loge(s, false);
- }
- protected void loge(String s, boolean stack) {
- if (stack) {
- Log.e(TAG, s + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
- + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
- + " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
- + " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
- } else {
- Log.e(TAG, s);
- }
- }
-
- private ScanDetailCache getScanDetailCache(WifiConfiguration config,
- Map<Integer, ScanDetailCache> scanDetailCaches) {
- if (config == null || scanDetailCaches == null) return null;
- ScanDetailCache cache = scanDetailCaches.get(config.networkId);
- if (cache == null && config.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
- cache =
- new ScanDetailCache(
- config, WifiConfigManager.SCAN_CACHE_ENTRIES_MAX_SIZE,
- WifiConfigManager.SCAN_CACHE_ENTRIES_TRIM_SIZE);
- scanDetailCaches.put(config.networkId, cache);
- }
- return cache;
- }
-}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 1d26f0448..38c767f94 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -4274,10 +4274,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
mLastSignalLevel = -1;
mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
- // Attempt to migrate data out of legacy store.
- if (!mWifiConfigManager.migrateFromLegacyStore()) {
- Log.e(TAG, "Failed to migrate from legacy config store");
- }
initializeWpsDetails();
sendSupplicantConnectionChangedBroadcast(true);
transitionTo(mSupplicantStartedState);
diff --git a/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfigParser.java b/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfigParser.java
deleted file mode 100644
index 31795f126..000000000
--- a/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfigParser.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.hotspot2;
-
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Utility class for parsing legacy (N and older) Passpoint configuration file content
- * (/data/misc/wifi/PerProviderSubscription.conf). In N and older, only Release 1 is supported.
- *
- * This class only retrieve the relevant Release 1 configuration fields that are not backed
- * elsewhere. Below are relevant fields:
- * - FQDN (used for linking with configuration data stored elsewhere)
- * - Friendly Name
- * - Roaming Consortium
- * - Realm
- * - IMSI (for SIM credential)
- *
- * Below is an example content of a Passpoint configuration file:
- *
- * tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)
- * 8:MgmtTree+
- * 17:PerProviderSubscription+
- * 4:r1i1+
- * 6:HomeSP+
- * c:FriendlyName=d:Test Provider
- * 4:FQDN=8:test.net
- * 13:RoamingConsortiumOI=9:1234,5678
- * .
- * a:Credential+
- * 10:UsernamePassword+
- * 8:Username=4:user
- * 8:Password=4:pass
- *
- * 9:EAPMethod+
- * 7:EAPType=2:21
- * b:InnerMethod=3:PAP
- * .
- * .
- * 5:Realm=a:boingo.com
- * .
- * .
- * .
- * .
- *
- * Each string is prefixed with a "|StringBytesInHex|:".
- * '+' indicates start of a new internal node.
- * '.' indicates end of the current internal node.
- * '=' indicates "value" of a leaf node.
- *
- */
-public class LegacyPasspointConfigParser {
- private static final String TAG = "LegacyPasspointConfigParser";
-
- private static final String TAG_MANAGEMENT_TREE = "MgmtTree";
- private static final String TAG_PER_PROVIDER_SUBSCRIPTION = "PerProviderSubscription";
- private static final String TAG_HOMESP = "HomeSP";
- private static final String TAG_FQDN = "FQDN";
- private static final String TAG_FRIENDLY_NAME = "FriendlyName";
- private static final String TAG_ROAMING_CONSORTIUM_OI = "RoamingConsortiumOI";
- private static final String TAG_CREDENTIAL = "Credential";
- private static final String TAG_REALM = "Realm";
- private static final String TAG_SIM = "SIM";
- private static final String TAG_IMSI = "IMSI";
-
- private static final String LONG_ARRAY_SEPARATOR = ",";
- private static final String END_OF_INTERNAL_NODE_INDICATOR = ".";
- private static final char START_OF_INTERNAL_NODE_INDICATOR = '+';
- private static final char STRING_PREFIX_INDICATOR = ':';
- private static final char STRING_VALUE_INDICATOR = '=';
-
- /**
- * An abstraction for a node within a tree. A node can be an internal node (contained
- * children nodes) or a leaf node (contained a String value).
- */
- private abstract static class Node {
- private final String mName;
- Node(String name) {
- mName = name;
- }
-
- /**
- * @return the name of the node
- */
- public String getName() {
- return mName;
- }
-
- /**
- * Applies for internal node only.
- *
- * @return the list of children nodes.
- */
- public abstract List<Node> getChildren();
-
- /**
- * Applies for leaf node only.
- *
- * @return the string value of the node
- */
- public abstract String getValue();
- }
-
- /**
- * Class representing an internal node of a tree. It contained a list of child nodes.
- */
- private static class InternalNode extends Node {
- private final List<Node> mChildren;
- InternalNode(String name, List<Node> children) {
- super(name);
- mChildren = children;
- }
-
- @Override
- public List<Node> getChildren() {
- return mChildren;
- }
-
- @Override
- public String getValue() {
- return null;
- }
- }
-
- /**
- * Class representing a leaf node of a tree. It contained a String type value.
- */
- private static class LeafNode extends Node {
- private final String mValue;
- LeafNode(String name, String value) {
- super(name);
- mValue = value;
- }
-
- @Override
- public List<Node> getChildren() {
- return null;
- }
-
- @Override
- public String getValue() {
- return mValue;
- }
- }
-
- public LegacyPasspointConfigParser() {}
-
- /**
- * Parse the legacy Passpoint configuration file content, only retrieve the relevant
- * configurations that are not saved elsewhere.
- *
- * For both N and M, only Release 1 is supported. Most of the configurations are saved
- * elsewhere as part of the {@link android.net.wifi.WifiConfiguration} data.
- * The configurations needed from the legacy Passpoint configuration file are:
- *
- * - FQDN - needed to be able to link to the associated {@link WifiConfiguration} data
- * - Friendly Name
- * - Roaming Consortium OIs
- * - Realm
- * - IMSI (for SIM credential)
- *
- * Make this function non-static so that it can be mocked during unit test.
- *
- * @param fileName The file name of the configuration file
- * @return Map of FQDN to {@link LegacyPasspointConfig}
- * @throws IOException
- */
- public Map<String, LegacyPasspointConfig> parseConfig(String fileName)
- throws IOException {
- Map<String, LegacyPasspointConfig> configs = new HashMap<>();
- BufferedReader in = new BufferedReader(new FileReader(fileName));
- in.readLine(); // Ignore the first line which contained the header.
-
- // Convert the configuration data to a management tree represented by a root {@link Node}.
- Node root = buildNode(in);
-
- if (root == null || root.getChildren() == null) {
- Log.d(TAG, "Empty configuration data");
- return configs;
- }
-
- // Verify root node name.
- if (!TextUtils.equals(TAG_MANAGEMENT_TREE, root.getName())) {
- throw new IOException("Unexpected root node: " + root.getName());
- }
-
- // Process and retrieve the configuration from each PPS (PerProviderSubscription) node.
- List<Node> ppsNodes = root.getChildren();
- for (Node ppsNode : ppsNodes) {
- LegacyPasspointConfig config = processPpsNode(ppsNode);
- configs.put(config.mFqdn, config);
- }
- return configs;
- }
-
- /**
- * Build a {@link Node} from the current line in the buffer. A node can be an internal
- * node (ends with '+') or a leaf node.
- *
- * @param in Input buffer to read data from
- * @return {@link Node} representing the current line
- * @throws IOException
- */
- private static Node buildNode(BufferedReader in) throws IOException {
- // Read until non-empty line.
- String currentLine = null;
- while ((currentLine = in.readLine()) != null) {
- if (!currentLine.isEmpty()) {
- break;
- }
- }
-
- // Return null if EOF is reached.
- if (currentLine == null) {
- return null;
- }
-
- // Remove the leading and the trailing whitespaces.
- currentLine = currentLine.trim();
-
- // Check for the internal node terminator.
- if (TextUtils.equals(END_OF_INTERNAL_NODE_INDICATOR, currentLine)) {
- return null;
- }
-
- // Parse the name-value of the current line. The value will be null if the current line
- // is not a leaf node (e.g. line ends with a '+').
- // Each line is encoded in UTF-8.
- Pair<String, String> nameValuePair =
- parseLine(currentLine.getBytes(StandardCharsets.UTF_8));
- if (nameValuePair.second != null) {
- return new LeafNode(nameValuePair.first, nameValuePair.second);
- }
-
- // Parse the children contained under this internal node.
- List<Node> children = new ArrayList<>();
- Node child = null;
- while ((child = buildNode(in)) != null) {
- children.add(child);
- }
- return new InternalNode(nameValuePair.first, children);
- }
-
- /**
- * Process a PPS (PerProviderSubscription) node to retrieve Passpoint configuration data.
- *
- * @param ppsNode The PPS node to process
- * @return {@link LegacyPasspointConfig}
- * @throws IOException
- */
- private static LegacyPasspointConfig processPpsNode(Node ppsNode) throws IOException {
- if (ppsNode.getChildren() == null || ppsNode.getChildren().size() != 1) {
- throw new IOException("PerProviderSubscription node should contain "
- + "one instance node");
- }
-
- if (!TextUtils.equals(TAG_PER_PROVIDER_SUBSCRIPTION, ppsNode.getName())) {
- throw new IOException("Unexpected name for PPS node: " + ppsNode.getName());
- }
-
- // Retrieve the PPS instance node.
- Node instanceNode = ppsNode.getChildren().get(0);
- if (instanceNode.getChildren() == null) {
- throw new IOException("PPS instance node doesn't contained any children");
- }
-
- // Process and retrieve the relevant configurations under the PPS instance node.
- LegacyPasspointConfig config = new LegacyPasspointConfig();
- for (Node node : instanceNode.getChildren()) {
- switch (node.getName()) {
- case TAG_HOMESP:
- processHomeSPNode(node, config);
- break;
- case TAG_CREDENTIAL:
- processCredentialNode(node, config);
- break;
- default:
- Log.d(TAG, "Ignore uninterested field under PPS instance: " + node.getName());
- break;
- }
- }
- if (config.mFqdn == null) {
- throw new IOException("PPS instance missing FQDN");
- }
- return config;
- }
-
- /**
- * Process a HomeSP node to retrieve configuration data into the given |config|.
- *
- * @param homeSpNode The HomeSP node to process
- * @param config The config object to fill in the data
- * @throws IOException
- */
- private static void processHomeSPNode(Node homeSpNode, LegacyPasspointConfig config)
- throws IOException {
- if (homeSpNode.getChildren() == null) {
- throw new IOException("HomeSP node should contain at least one child node");
- }
-
- for (Node node : homeSpNode.getChildren()) {
- switch (node.getName()) {
- case TAG_FQDN:
- config.mFqdn = getValue(node);
- break;
- case TAG_FRIENDLY_NAME:
- config.mFriendlyName = getValue(node);
- break;
- case TAG_ROAMING_CONSORTIUM_OI:
- config.mRoamingConsortiumOis = parseLongArray(getValue(node));
- break;
- default:
- Log.d(TAG, "Ignore uninterested field under HomeSP: " + node.getName());
- break;
- }
- }
- }
-
- /**
- * Process a Credential node to retrieve configuration data into the given |config|.
- *
- * @param credentialNode The Credential node to process
- * @param config The config object to fill in the data
- * @throws IOException
- */
- private static void processCredentialNode(Node credentialNode,
- LegacyPasspointConfig config)
- throws IOException {
- if (credentialNode.getChildren() == null) {
- throw new IOException("Credential node should contain at least one child node");
- }
-
- for (Node node : credentialNode.getChildren()) {
- switch (node.getName()) {
- case TAG_REALM:
- config.mRealm = getValue(node);
- break;
- case TAG_SIM:
- processSimNode(node, config);
- break;
- default:
- Log.d(TAG, "Ignore uninterested field under Credential: " + node.getName());
- break;
- }
- }
- }
-
- /**
- * Process a SIM node to retrieve configuration data into the given |config|.
- *
- * @param simNode The SIM node to process
- * @param config The config object to fill in the data
- * @throws IOException
- */
- private static void processSimNode(Node simNode, LegacyPasspointConfig config)
- throws IOException {
- if (simNode.getChildren() == null) {
- throw new IOException("SIM node should contain at least one child node");
- }
-
- for (Node node : simNode.getChildren()) {
- switch (node.getName()) {
- case TAG_IMSI:
- config.mImsi = getValue(node);
- break;
- default:
- Log.d(TAG, "Ignore uninterested field under SIM: " + node.getName());
- break;
- }
- }
- }
-
- /**
- * Parse the given line in the legacy Passpoint configuration file.
- * A line can be in the following formats:
- * 2:ab+ // internal node
- * 2:ab=2:bc // leaf node
- * . // end of internal node
- *
- * @param line The line to parse
- * @return name-value pair, a value of null indicates internal node
- * @throws IOException
- */
- private static Pair<String, String> parseLine(byte[] lineBytes) throws IOException {
- Pair<String, Integer> nameIndexPair = parseString(lineBytes, 0);
- int currentIndex = nameIndexPair.second;
- try {
- if (lineBytes[currentIndex] == START_OF_INTERNAL_NODE_INDICATOR) {
- return Pair.create(nameIndexPair.first, null);
- }
-
- if (lineBytes[currentIndex] != STRING_VALUE_INDICATOR) {
- throw new IOException("Invalid line - missing both node and value indicator: "
- + new String(lineBytes, StandardCharsets.UTF_8));
- }
- } catch (IndexOutOfBoundsException e) {
- throw new IOException("Invalid line - " + e.getMessage() + ": "
- + new String(lineBytes, StandardCharsets.UTF_8));
- }
- Pair<String, Integer> valueIndexPair = parseString(lineBytes, currentIndex + 1);
- return Pair.create(nameIndexPair.first, valueIndexPair.first);
- }
-
- /**
- * Parse a string value in the given line from the given start index.
- * A string value is in the following format:
- * |HexByteLength|:|String|
- *
- * The length value indicates the number of UTF-8 bytes in hex for the given string.
- *
- * For example: 3:abc
- *
- * @param lineBytes The UTF-8 bytes of the line to parse
- * @param startIndex The start index from the given line to parse from
- * @return Pair of a string value and an index pointed to character after the string value
- * @throws IOException
- */
- private static Pair<String, Integer> parseString(byte[] lineBytes, int startIndex)
- throws IOException {
- // Locate the index that separate length and the string value.
- int prefixIndex = -1;
- for (int i = startIndex; i < lineBytes.length; i++) {
- if (lineBytes[i] == STRING_PREFIX_INDICATOR) {
- prefixIndex = i;
- break;
- }
- }
- if (prefixIndex == -1) {
- throw new IOException("Invalid line - missing string prefix: "
- + new String(lineBytes, StandardCharsets.UTF_8));
- }
-
- try {
- String lengthStr = new String(lineBytes, startIndex, prefixIndex - startIndex,
- StandardCharsets.UTF_8);
- int length = Integer.parseInt(lengthStr, 16);
- int strStartIndex = prefixIndex + 1;
- // The length might account for bytes for the whitespaces, since the whitespaces are
- // already trimmed, ignore them.
- if ((strStartIndex + length) > lineBytes.length) {
- length = lineBytes.length - strStartIndex;
- }
- return Pair.create(
- new String(lineBytes, strStartIndex, length, StandardCharsets.UTF_8),
- strStartIndex + length);
- } catch (NumberFormatException | IndexOutOfBoundsException e) {
- throw new IOException("Invalid line - " + e.getMessage() + ": "
- + new String(lineBytes, StandardCharsets.UTF_8));
- }
- }
-
- /**
- * Parse a long array from the given string.
- *
- * @param str The string to parse
- * @return long[]
- * @throws IOException
- */
- private static long[] parseLongArray(String str)
- throws IOException {
- String[] strArray = str.split(LONG_ARRAY_SEPARATOR);
- long[] longArray = new long[strArray.length];
- for (int i = 0; i < longArray.length; i++) {
- try {
- longArray[i] = Long.parseLong(strArray[i], 16);
- } catch (NumberFormatException e) {
- throw new IOException("Invalid long integer value: " + strArray[i]);
- }
- }
- return longArray;
- }
-
- /**
- * Get the String value of the given node. An IOException will be thrown if the given
- * node doesn't contain a String value (internal node).
- *
- * @param node The node to get the value from
- * @return String
- * @throws IOException
- */
- private static String getValue(Node node) throws IOException {
- if (node.getValue() == null) {
- throw new IOException("Attempt to retreive value from non-leaf node: "
- + node.getName());
- }
- return node.getValue();
- }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 70f660e8e..d14c8fc9f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -43,7 +43,6 @@ import android.text.TextUtils;
import android.util.Pair;
import com.android.internal.R;
-import com.android.server.wifi.WifiConfigStoreLegacy.WifiConfigStoreDataLegacy;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -101,7 +100,6 @@ public class WifiConfigManagerTest {
@Mock private TelephonyManager mTelephonyManager;
@Mock private WifiKeyStore mWifiKeyStore;
@Mock private WifiConfigStore mWifiConfigStore;
- @Mock private WifiConfigStoreLegacy mWifiConfigStoreLegacy;
@Mock private PackageManager mPackageManager;
@Mock private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
@Mock private WifiPermissionsUtil mWifiPermissionsUtil;
@@ -2539,74 +2537,6 @@ public class WifiConfigManagerTest {
}
/**
- * Verifies the loading of networks using {@link WifiConfigManager#migrateFromLegacyStore()} ()}
- * attempts to migrate data from legacy stores when the legacy store files are present.
- */
- @Test
- public void testMigrationFromLegacyStore() throws Exception {
- // Create the store data to be returned from legacy stores.
- List<WifiConfiguration> networks = new ArrayList<>();
- networks.add(WifiConfigurationTestUtil.createPskNetwork());
- networks.add(WifiConfigurationTestUtil.createEapNetwork());
- networks.add(WifiConfigurationTestUtil.createWepNetwork());
- String deletedEphemeralSSID = "EphemeralSSID";
- Set<String> deletedEphermalSSIDs = new HashSet<>(Arrays.asList(deletedEphemeralSSID));
- WifiConfigStoreDataLegacy storeData =
- new WifiConfigStoreDataLegacy(networks, deletedEphermalSSIDs);
-
- when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(true);
- when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
- when(mWifiConfigStoreLegacy.read()).thenReturn(storeData);
-
- // Now trigger the migration from legacy store. This should populate the in memory list with
- // all the networks above from the legacy store.
- assertTrue(mWifiConfigManager.migrateFromLegacyStore());
-
- verify(mWifiConfigStoreLegacy).read();
- verify(mWifiConfigStoreLegacy).removeStores();
-
- List<WifiConfiguration> retrievedNetworks =
- mWifiConfigManager.getConfiguredNetworksWithPasswords();
- WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
- networks, retrievedNetworks);
- assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(deletedEphemeralSSID));
- }
-
- /**
- * Verifies the loading of networks using {@link WifiConfigManager#migrateFromLegacyStore()} ()}
- * does not attempt to migrate data from legacy stores when the legacy store files are absent
- * (i.e migration was already done once).
- */
- @Test
- public void testNoDuplicateMigrationFromLegacyStore() throws Exception {
- when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
-
- // Now trigger a migration from legacy store.
- assertTrue(mWifiConfigManager.migrateFromLegacyStore());
-
- verify(mWifiConfigStoreLegacy, never()).read();
- verify(mWifiConfigStoreLegacy, never()).removeStores();
- }
-
- /**
- * Verifies the loading of networks using {@link WifiConfigManager#migrateFromLegacyStore()} ()}
- * does not attempt to migrate data from legacy stores when the new store files are present
- * (i.e migration was already done once).
- */
- @Test
- public void testNewStoreFilesPresentNoMigrationFromLegacyStore() throws Exception {
- when(mWifiConfigStore.areStoresPresent()).thenReturn(true);
- when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(true);
-
- // Now trigger a migration from legacy store.
- assertTrue(mWifiConfigManager.migrateFromLegacyStore());
-
- verify(mWifiConfigStoreLegacy, never()).read();
- // Verify that we went ahead and deleted the old store files.
- verify(mWifiConfigStoreLegacy).removeStores();
- }
-
- /**
* Verifies the loading of networks using {@link WifiConfigManager#loadFromStore()} does
* not attempt to read from any of the stores (new or legacy) when the store files are
* not present.
@@ -2614,12 +2544,10 @@ public class WifiConfigManagerTest {
@Test
public void testFreshInstallDoesNotLoadFromStore() throws Exception {
when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
- when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
assertTrue(mWifiConfigManager.loadFromStore());
verify(mWifiConfigStore, never()).read();
- verify(mWifiConfigStoreLegacy, never()).read();
assertTrue(mWifiConfigManager.getConfiguredNetworksWithPasswords().isEmpty());
}
@@ -2632,11 +2560,9 @@ public class WifiConfigManagerTest {
public void testHandleUserSwitchAfterFreshInstall() throws Exception {
int user2 = TEST_DEFAULT_USER + 1;
when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
- when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
assertTrue(mWifiConfigManager.loadFromStore());
verify(mWifiConfigStore, never()).read();
- verify(mWifiConfigStoreLegacy, never()).read();
setupStoreDataForUserRead(new ArrayList<WifiConfiguration>(), new HashSet<String>());
// Now switch the user to user 2.
@@ -3395,7 +3321,7 @@ public class WifiConfigManagerTest {
mWifiConfigManager =
new WifiConfigManager(
mContext, mClock, mUserManager, mTelephonyManager,
- mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy,
+ mWifiKeyStore, mWifiConfigStore,
mWifiPermissionsUtil, mWifiPermissionsWrapper, mNetworkListStoreData,
mDeletedEphemeralSsidsStoreData);
mWifiConfigManager.enableVerboseLogging(1);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java
deleted file mode 100644
index 4b4e875a1..000000000
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-
-import android.app.test.MockAnswerUtil.AnswerWithArguments;
-import android.net.IpConfiguration;
-import android.net.wifi.WifiConfiguration;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-import android.util.SparseArray;
-
-import com.android.server.net.IpConfigStore;
-import com.android.server.wifi.hotspot2.LegacyPasspointConfig;
-import com.android.server.wifi.hotspot2.LegacyPasspointConfigParser;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for {@link com.android.server.wifi.WifiConfigStoreLegacy}.
- */
-@SmallTest
-public class WifiConfigStoreLegacyTest {
- private static final String MASKED_FIELD_VALUE = "*";
-
- // Test mocks
- @Mock private WifiNative mWifiNative;
- @Mock private WifiNetworkHistory mWifiNetworkHistory;
- @Mock private IpConfigStore mIpconfigStore;
- @Mock private LegacyPasspointConfigParser mPasspointConfigParser;
-
- /**
- * Test instance of WifiConfigStore.
- */
- private WifiConfigStoreLegacy mWifiConfigStore;
-
-
- /**
- * Setup the test environment.
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mWifiConfigStore = new WifiConfigStoreLegacy(mWifiNetworkHistory, mWifiNative,
- mIpconfigStore, mPasspointConfigParser);
- }
-
- /**
- * Called after each test
- */
- @After
- public void cleanup() {
- validateMockitoUsage();
- }
-
- /**
- * Verify loading of network configurations from legacy stores. This is verifying the population
- * of the masked wpa_supplicant fields using wpa_supplicant.conf file.
- */
- @Test
- public void testLoadFromStores() throws Exception {
- WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
- WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
- WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
- WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
- eapNetwork.enterpriseConfig.setPassword("EapPassword");
-
- // Initialize Passpoint configuration data.
- int passpointNetworkId = 1234;
- String fqdn = passpointNetwork.FQDN;
- String providerFriendlyName = passpointNetwork.providerFriendlyName;
- long[] roamingConsortiumIds = new long[] {0x1234, 0x5678};
- String realm = "test.com";
- String imsi = "214321";
-
- // Update Passpoint network.
- // Network ID is used for lookup network extras, so use an unique ID for passpoint network.
- passpointNetwork.networkId = passpointNetworkId;
- passpointNetwork.enterpriseConfig.setPassword("PaspointPassword");
- // Reset FQDN and provider friendly name so that the derived network from #read will
- // obtained these information from networkExtras and {@link LegacyPasspointConfigParser}.
- passpointNetwork.FQDN = null;
- passpointNetwork.providerFriendlyName = null;
-
- final List<WifiConfiguration> networks = new ArrayList<>();
- networks.add(pskNetwork);
- networks.add(wepNetwork);
- networks.add(eapNetwork);
- networks.add(passpointNetwork);
-
- // Setup legacy Passpoint configuration data.
- Map<String, LegacyPasspointConfig> passpointConfigs = new HashMap<>();
- LegacyPasspointConfig passpointConfig = new LegacyPasspointConfig();
- passpointConfig.mFqdn = fqdn;
- passpointConfig.mFriendlyName = providerFriendlyName;
- passpointConfig.mRoamingConsortiumOis = roamingConsortiumIds;
- passpointConfig.mRealm = realm;
- passpointConfig.mImsi = imsi;
- passpointConfigs.put(fqdn, passpointConfig);
-
- // Return the config data with passwords masked from wpa_supplicant control interface.
- doAnswer(new AnswerWithArguments() {
- public boolean answer(Map<String, WifiConfiguration> configs,
- SparseArray<Map<String, String>> networkExtras) {
- for (Map.Entry<String, WifiConfiguration> entry:
- createWpaSupplicantLoadData(networks).entrySet()) {
- configs.put(entry.getKey(), entry.getValue());
- }
- // Setup networkExtras for Passpoint configuration.
- networkExtras.put(passpointNetworkId, createNetworkExtrasForPasspointConfig(fqdn));
- return true;
- }
- }).when(mWifiNative).migrateNetworksFromSupplicant(any(Map.class), any(SparseArray.class));
-
- when(mPasspointConfigParser.parseConfig(anyString())).thenReturn(passpointConfigs);
- WifiConfigStoreLegacy.WifiConfigStoreDataLegacy storeData = mWifiConfigStore.read();
-
- // Update the expected configuration for Passpoint network.
- passpointNetwork.isLegacyPasspointConfig = true;
- passpointNetwork.FQDN = fqdn;
- passpointNetwork.providerFriendlyName = providerFriendlyName;
- passpointNetwork.roamingConsortiumIds = roamingConsortiumIds;
- passpointNetwork.enterpriseConfig.setRealm(realm);
- passpointNetwork.enterpriseConfig.setPlmn(imsi);
-
- WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore(
- networks, storeData.getConfigurations());
- }
-
- private SparseArray<IpConfiguration> createIpConfigStoreLoadData(
- List<WifiConfiguration> configurations) {
- SparseArray<IpConfiguration> newIpConfigurations = new SparseArray<>();
- for (WifiConfiguration config : configurations) {
- newIpConfigurations.put(
- config.configKey().hashCode(),
- new IpConfiguration(config.getIpConfiguration()));
- }
- return newIpConfigurations;
- }
-
- private Map<String, String> createPskMap(List<WifiConfiguration> configurations) {
- Map<String, String> pskMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.preSharedKey)) {
- pskMap.put(config.configKey(), config.preSharedKey);
- }
- }
- return pskMap;
- }
-
- private Map<String, String> createWepKey0Map(List<WifiConfiguration> configurations) {
- Map<String, String> wepKeyMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.wepKeys[0])) {
- wepKeyMap.put(config.configKey(), config.wepKeys[0]);
- }
- }
- return wepKeyMap;
- }
-
- private Map<String, String> createWepKey1Map(List<WifiConfiguration> configurations) {
- Map<String, String> wepKeyMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.wepKeys[1])) {
- wepKeyMap.put(config.configKey(), config.wepKeys[1]);
- }
- }
- return wepKeyMap;
- }
-
- private Map<String, String> createWepKey2Map(List<WifiConfiguration> configurations) {
- Map<String, String> wepKeyMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.wepKeys[2])) {
- wepKeyMap.put(config.configKey(), config.wepKeys[2]);
- }
- }
- return wepKeyMap;
- }
-
- private Map<String, String> createWepKey3Map(List<WifiConfiguration> configurations) {
- Map<String, String> wepKeyMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.wepKeys[3])) {
- wepKeyMap.put(config.configKey(), config.wepKeys[3]);
- }
- }
- return wepKeyMap;
- }
-
- private Map<String, String> createEapPasswordMap(List<WifiConfiguration> configurations) {
- Map<String, String> eapPasswordMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- if (!TextUtils.isEmpty(config.enterpriseConfig.getPassword())) {
- eapPasswordMap.put(config.configKey(), config.enterpriseConfig.getPassword());
- }
- }
- return eapPasswordMap;
- }
-
- private Map<String, WifiConfiguration> createWpaSupplicantLoadData(
- List<WifiConfiguration> configurations) {
- Map<String, WifiConfiguration> configurationMap = new HashMap<>();
- for (WifiConfiguration config : configurations) {
- configurationMap.put(config.configKey(true), config);
- }
- return configurationMap;
- }
-
- private List<WifiConfiguration> createMaskedWifiConfigurations(
- List<WifiConfiguration> configurations) {
- List<WifiConfiguration> newConfigurations = new ArrayList<>();
- for (WifiConfiguration config : configurations) {
- newConfigurations.add(createMaskedWifiConfiguration(config));
- }
- return newConfigurations;
- }
-
- private WifiConfiguration createMaskedWifiConfiguration(WifiConfiguration configuration) {
- WifiConfiguration newConfig = new WifiConfiguration(configuration);
- if (!TextUtils.isEmpty(configuration.preSharedKey)) {
- newConfig.preSharedKey = MASKED_FIELD_VALUE;
- }
- if (!TextUtils.isEmpty(configuration.wepKeys[0])) {
- newConfig.wepKeys[0] = MASKED_FIELD_VALUE;
- }
- if (!TextUtils.isEmpty(configuration.wepKeys[1])) {
- newConfig.wepKeys[1] = MASKED_FIELD_VALUE;
- }
- if (!TextUtils.isEmpty(configuration.wepKeys[2])) {
- newConfig.wepKeys[2] = MASKED_FIELD_VALUE;
- }
- if (!TextUtils.isEmpty(configuration.wepKeys[3])) {
- newConfig.wepKeys[3] = MASKED_FIELD_VALUE;
- }
- if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
- newConfig.enterpriseConfig.setPassword(MASKED_FIELD_VALUE);
- }
- return newConfig;
- }
-
- private Map<String, String> createNetworkExtrasForPasspointConfig(String fqdn) {
- Map<String, String> extras = new HashMap<>();
- extras.put(SupplicantStaNetworkHal.ID_STRING_KEY_FQDN, fqdn);
- return extras;
- }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/LegacyPasspointConfigParserTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/LegacyPasspointConfigParserTest.java
deleted file mode 100644
index 10ebceb22..000000000
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/LegacyPasspointConfigParserTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.hotspot2;
-
-import static org.junit.Assert.*;
-
-import android.os.FileUtils;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for {@link com.android.server.wifi.hotspot2.LegacyPasspointConfigParser}.
- */
-@SmallTest
-public class LegacyPasspointConfigParserTest {
- private static final String TEST_CONFIG =
- "tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)\n"
- + "8:MgmtTree+\n"
- + "17:PerProviderSubscription+\n"
- + "4:r1i1+\n"
- + "6:HomeSP+\n"
- + "c:FriendlyName=12:Test Provider 1™\n"
- + "4:FQDN=9:test1.net\n"
- + "13:RoamingConsortiumOI=9:1234,5678\n"
- + ".\n"
- + "a:Credential+\n"
- + "10:UsernamePassword+\n"
- + "8:Username=5:user1\n"
- + "8:Password=5:pass1\n"
- + "\n"
- + "9:EAPMethod+\n"
- + "7:EAPType=2:21\n"
- + "b:InnerMethod=3:PAP\n"
- + ".\n"
- + ".\n"
- + "5:Realm=9:test1.com\n"
- + ".\n"
- + ".\n"
- + ".\n"
- + "17:PerProviderSubscription+\n"
- + "4:r1i2+\n"
- + "6:HomeSP+\n"
- + "c:FriendlyName=f:Test Provider 2\n"
- + "4:FQDN=9:test2.net\n"
- + ".\n"
- + "a:Credential+\n"
- + "3:SIM+\n"
- + "4:IMSI=4:1234\n"
- + "7:EAPType=2:18\n"
- + ".\n"
- + "5:Realm=9:test2.com\n"
- + ".\n"
- + ".\n"
- + ".\n"
- + ".\n";
-
- /**
- * Helper function for generating {@link LegacyPasspointConfig} objects based on the predefined
- * test configuration string {@link #TEST_CONFIG}
- *
- * @return Map of FQDN to {@link LegacyPasspointConfig}
- */
- private Map<String, LegacyPasspointConfig> generateTestConfig() {
- Map<String, LegacyPasspointConfig> configs = new HashMap<>();
-
- LegacyPasspointConfig config1 = new LegacyPasspointConfig();
- config1.mFqdn = "test1.net";
- config1.mFriendlyName = "Test Provider 1™";
- config1.mRoamingConsortiumOis = new long[] {0x1234, 0x5678};
- config1.mRealm = "test1.com";
- configs.put("test1.net", config1);
-
- LegacyPasspointConfig config2 = new LegacyPasspointConfig();
- config2.mFqdn = "test2.net";
- config2.mFriendlyName = "Test Provider 2";
- config2.mRealm = "test2.com";
- config2.mImsi = "1234";
- configs.put("test2.net", config2);
-
- return configs;
- }
-
- /**
- * Helper function for parsing configuration data.
- *
- * @param data The configuration data to parse
- * @return Map of FQDN to {@link LegacyPasspointConfig}
- * @throws Exception
- */
- private Map<String, LegacyPasspointConfig> parseConfig(String data) throws Exception {
- // Write configuration data to file.
- File configFile = File.createTempFile("LegacyPasspointConfig", "");
- FileUtils.stringToFile(configFile, data);
-
- // Parse the configuration file.
- LegacyPasspointConfigParser parser = new LegacyPasspointConfigParser();
- Map<String, LegacyPasspointConfig> configMap =
- parser.parseConfig(configFile.getAbsolutePath());
-
- configFile.delete();
- return configMap;
- }
-
- /**
- * Verify that the expected {@link LegacyPasspointConfig} objects are return when parsing
- * predefined test configuration data {@link #TEST_CONFIG}.
- *
- * @throws Exception
- */
- @Test
- public void parseTestConfig() throws Exception {
- Map<String, LegacyPasspointConfig> parsedConfig = parseConfig(TEST_CONFIG);
- assertEquals(generateTestConfig(), parsedConfig);
- }
-
- /**
- * Verify that an empty map is return when parsing a configuration containing an empty
- * configuration (MgmtTree).
- *
- * @throws Exception
- */
- @Test
- public void parseEmptyConfig() throws Exception {
- String emptyConfig = "tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)\n"
- + "8:MgmtTree+\n"
- + ".\n";
- Map<String, LegacyPasspointConfig> parsedConfig = parseConfig(emptyConfig);
- assertTrue(parsedConfig.isEmpty());
- }
-
- /**
- * Verify that an empty map is return when parsing an empty configuration data.
- *
- * @throws Exception
- */
- @Test
- public void parseEmptyData() throws Exception {
- Map<String, LegacyPasspointConfig> parsedConfig = parseConfig("");
- assertTrue(parsedConfig.isEmpty());
- }
-
- /**
- * Verify that an IOException is thrown when parsing a configuration containing an unknown
- * root name. The expected root name is "MgmtTree".
- *
- * @throws Exception
- */
- @Test(expected = IOException.class)
- public void parseConfigWithUnknownRootName() throws Exception {
- String config = "tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)\n"
- + "8:TestTest+\n"
- + ".\n";
- parseConfig(config);
- }
-
- /**
- * Verify that an IOException is thrown when parsing a configuration containing a line with
- * mismatched string length for the name.
- *
- * @throws Exception
- */
- @Test(expected = IOException.class)
- public void parseConfigWithMismatchedStringLengthInName() throws Exception {
- String config = "tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)\n"
- + "9:MgmtTree+\n"
- + ".\n";
- parseConfig(config);
- }
-
- /**
- * Verify that an IOException is thrown when parsing a configuration containing a line with
- * mismatched string length for the value.
- *
- * @throws Exception
- */
- @Test(expected = IOException.class)
- public void parseConfigWithMismatchedStringLengthInValue() throws Exception {
- String config = "tree 3:1.2(urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0)\n"
- + "8:MgmtTree+\n"
- + "4:test=5:test\n"
- + ".\n";
- parseConfig(config);
- }
-}