summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2016-06-07 22:10:43 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-06-07 22:10:43 +0000
commitd09a68e978eafe26ff100fd1c34c5051293d8373 (patch)
tree66a1040e43adea876ff185cdcd3123e5bf645ff9 /service
parent1286b0044ec003ab4a765e124fb3dd985baa2d2c (diff)
parente33a4bb414892435c016486585c26022cafdab68 (diff)
Merge "XmlUtil: Move Wifi/IP-Configuration serialization"
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiBackupRestore.java426
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java522
2 files changed, 558 insertions, 390 deletions
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index c37a70c8d..5de29a2c2 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -17,21 +17,17 @@
package com.android.server.wifi;
import android.net.IpConfiguration;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.net.IpConfigStore;
import com.android.server.wifi.util.XmlUtil;
+import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -45,17 +41,11 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.List;
import java.util.Map;
-import static android.net.IpConfiguration.IpAssignment;
-import static android.net.IpConfiguration.ProxySettings;
-
/**
* Class used to backup/restore data using the SettingsBackupAgent.
* There are 2 symmetric API's exposed here:
@@ -79,41 +69,20 @@ public class WifiBackupRestore {
private static final int INITIAL_BACKUP_DATA_VERSION = 1;
/**
- * List of XML tags in the backed up data
+ * List of XML section header tags in the backed up data
*/
private static final String XML_TAG_DOCUMENT_HEADER = "WifiBackupData";
private static final String XML_TAG_VERSION = "Version";
- private static final String XML_TAG_SECTION_HEADER_CONFIGURATION_LIST = "ConfigurationList";
- private static final String XML_TAG_SECTION_HEADER_CONFIGURATION = "Configuration";
- private static final String XML_TAG_CONFIGURATION_SSID = "SSID";
- private static final String XML_TAG_CONFIGURATION_BSSID = "BSSID";
- private static final String XML_TAG_CONFIGURATION_CONFIG_KEY = "ConfigKey";
- private static final String XML_TAG_CONFIGURATION_PRE_SHARED_KEY = "PreSharedKey";
- private static final String XML_TAG_CONFIGURATION_WEP_KEYS = "WEPKeys";
- private static final String XML_TAG_CONFIGURATION_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
- private static final String XML_TAG_CONFIGURATION_HIDDEN_SSID = "HiddenSSID";
- private static final String XML_TAG_CONFIGURATION_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
- private static final String XML_TAG_CONFIGURATION_ALLOWED_PROTOCOLS = "AllowedProtocols";
- private static final String XML_TAG_CONFIGURATION_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
- private static final String XML_TAG_CONFIGURATION_SHARED = "Shared";
- private static final String XML_TAG_CONFIGURATION_CREATOR_UID = "CreatorUid";
+ private static final String XML_TAG_SECTION_HEADER_NETWORK_LIST = "NetworkList";
+ private static final String XML_TAG_SECTION_HEADER_NETWORK = "Network";
+ private static final String XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION = "WifiConfiguration";
private static final String XML_TAG_SECTION_HEADER_IP_CONFIGURATION = "IpConfiguration";
- private static final String XML_TAG_IP_CONFIGURATION_IP_ASSIGNMENT = "IpAssignment";
- private static final String XML_TAG_IP_CONFIGURATION_LINK_ADDRESS = "LinkAddress";
- private static final String XML_TAG_IP_CONFIGURATION_LINK_PREFIX_LENGTH = "LinkPrefixLength";
- private static final String XML_TAG_IP_CONFIGURATION_GATEWAY_ADDRESS = "GatewayAddress";
- private static final String XML_TAG_IP_CONFIGURATION_DNS_SERVER_ADDRESSES = "DNSServers";
- private static final String XML_TAG_IP_CONFIGURATION_PROXY_SETTINGS = "ProxySettings";
- private static final String XML_TAG_IP_CONFIGURATION_PROXY_HOST = "ProxyHost";
- private static final String XML_TAG_IP_CONFIGURATION_PROXY_PORT = "ProxyPort";
- private static final String XML_TAG_IP_CONFIGURATION_PROXY_PAC_FILE = "ProxyPac";
- private static final String XML_TAG_IP_CONFIGURATION_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
/**
* Regex to mask out passwords in backup data dump.
*/
private static final String PASSWORD_MASK_SEARCH_PATTERN =
- "(<.*" + XML_TAG_CONFIGURATION_PRE_SHARED_KEY + ".*>)(.*)(<.*>)";
+ "(<.*" + WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY + ".*>)(.*)(<.*>)";
private static final String PASSWORD_MASK_REPLACE_PATTERN = "$1*$3";
/**
@@ -152,7 +121,7 @@ public class WifiBackupRestore {
XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_BACKUP_DATA_VERSION);
- writeWifiConfigurationsToXml(out, configurations);
+ writeNetworkConfigurationsToXml(out, configurations);
XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
@@ -174,10 +143,10 @@ public class WifiBackupRestore {
/**
* Write the list of configurations to the XML stream.
*/
- private void writeWifiConfigurationsToXml(
+ private void writeNetworkConfigurationsToXml(
XmlSerializer out, List<WifiConfiguration> configurations)
throws XmlPullParserException, IOException {
- XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_CONFIGURATION_LIST);
+ XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
for (WifiConfiguration configuration : configurations) {
// We don't want to backup/restore enterprise/passpoint configurations.
if (configuration.isEnterprise() || configuration.isPasspoint()) {
@@ -185,151 +154,31 @@ public class WifiBackupRestore {
continue;
}
// Write this configuration data now.
- XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_CONFIGURATION);
- writeWifiConfigurationToXml(out, configuration);
- XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_CONFIGURATION);
- }
- XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_CONFIGURATION_LIST);
- }
-
- /**
- * Write WepKeys to the XML stream.
- * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
- * are null. XmlUtils serialization doesn't handle this array of nulls well .
- * So, write null if the keys are not initialized.
- */
- private void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
- throws XmlPullParserException, IOException {
- if (wepKeys[0] != null) {
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_WEP_KEYS, wepKeys);
- } else {
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_WEP_KEYS, null);
+ XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK);
+ writeNetworkConfigurationToXml(out, configuration);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK);
}
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
}
/**
* Write the configuration data elements from the provided Configuration to the XML stream.
* Uses XmlUtils to write the values of each element.
*/
- private void writeWifiConfigurationToXml(XmlSerializer out, WifiConfiguration configuration)
+ private void writeNetworkConfigurationToXml(XmlSerializer out, WifiConfiguration configuration)
throws XmlPullParserException, IOException {
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_CONFIG_KEY, configuration.configKey());
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_SSID, configuration.SSID);
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_BSSID, configuration.BSSID);
- XmlUtil.writeNextValue(
- out, XML_TAG_CONFIGURATION_PRE_SHARED_KEY, configuration.preSharedKey);
- writeWepKeysToXml(out, configuration.wepKeys);
- XmlUtil.writeNextValue(
- out, XML_TAG_CONFIGURATION_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_HIDDEN_SSID, configuration.hiddenSSID);
- XmlUtil.writeNextValue(
- out, XML_TAG_CONFIGURATION_ALLOWED_KEY_MGMT,
- configuration.allowedKeyManagement.toByteArray());
- XmlUtil.writeNextValue(
- out, XML_TAG_CONFIGURATION_ALLOWED_PROTOCOLS,
- configuration.allowedProtocols.toByteArray());
- XmlUtil.writeNextValue(
- out, XML_TAG_CONFIGURATION_ALLOWED_AUTH_ALGOS,
- configuration.allowedAuthAlgorithms.toByteArray());
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_SHARED, configuration.shared);
- XmlUtil.writeNextValue(out, XML_TAG_CONFIGURATION_CREATOR_UID, configuration.creatorUid);
-
+ XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
+ WifiConfigurationXmlUtil.writeWifiConfigurationToXmlForBackup(out, configuration);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
if (configuration.getIpConfiguration() != null) {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
- writeIpConfigurationToXml(out, configuration.getIpConfiguration());
+ IpConfigurationXmlUtil.writeIpConfigurationToXml(
+ out, configuration.getIpConfiguration());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
}
}
/**
- * Write the static IP configuration data elements to XML stream
- */
- private void writeStaticIpConfigurationToXml(XmlSerializer out,
- StaticIpConfiguration staticIpConfiguration)
- throws XmlPullParserException, IOException {
- if (staticIpConfiguration.ipAddress != null) {
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_LINK_ADDRESS,
- staticIpConfiguration.ipAddress.getAddress().getHostAddress());
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_LINK_PREFIX_LENGTH,
- staticIpConfiguration.ipAddress.getPrefixLength());
- } else {
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_LINK_ADDRESS, null);
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_LINK_PREFIX_LENGTH, null);
- }
- if (staticIpConfiguration.gateway != null) {
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_GATEWAY_ADDRESS,
- staticIpConfiguration.gateway.getHostAddress());
- } else {
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_GATEWAY_ADDRESS, null);
-
- }
- if (staticIpConfiguration.dnsServers != null) {
- // Create a string array of DNS server addresses
- String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
- int dnsServerIdx = 0;
- for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
- dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
- }
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_DNS_SERVER_ADDRESSES, dnsServers);
- } else {
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_DNS_SERVER_ADDRESSES, null);
- }
- }
-
- /**
- * Write the IP configuration data elements from the provided Configuration to the XML stream.
- * Uses XmlUtils to write the values of each element.
- */
- private void writeIpConfigurationToXml(XmlSerializer out, IpConfiguration ipConfiguration)
- throws XmlPullParserException, IOException {
-
- // Write IP assignment settings
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_IP_ASSIGNMENT,
- ipConfiguration.ipAssignment.toString());
- switch (ipConfiguration.ipAssignment) {
- case STATIC:
- writeStaticIpConfigurationToXml(out, ipConfiguration.getStaticIpConfiguration());
- break;
- default:
- break;
- }
-
- // Write proxy settings
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_PROXY_SETTINGS,
- ipConfiguration.proxySettings.toString());
- switch (ipConfiguration.proxySettings) {
- case STATIC:
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_PROXY_HOST,
- ipConfiguration.httpProxy.getHost());
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_PROXY_PORT,
- ipConfiguration.httpProxy.getPort());
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_PROXY_EXCLUSION_LIST,
- ipConfiguration.httpProxy.getExclusionListAsString());
- break;
- case PAC:
- XmlUtil.writeNextValue(
- out, XML_TAG_IP_CONFIGURATION_PROXY_PAC_FILE,
- ipConfiguration.httpProxy.getPacFileUrl().toString());
- break;
- default:
- break;
- }
- }
-
- /**
* Parse out the configurations from the back up data.
*
* @param data raw byte stream representing the XML data.
@@ -354,13 +203,13 @@ public class WifiBackupRestore {
XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
int rootTagDepth = in.getDepth();
- int version = (int) XmlUtil.readNextValue(in, XML_TAG_VERSION);
+ int version = (int) XmlUtil.readNextValueWithName(in, XML_TAG_VERSION);
if (version < INITIAL_BACKUP_DATA_VERSION || version > CURRENT_BACKUP_DATA_VERSION) {
Log.e(TAG, "Invalid version of data: " + version);
return null;
}
- return parseWifiConfigurationsFromXml(in, rootTagDepth, version);
+ return parseNetworkConfigurationsFromXml(in, rootTagDepth, version);
} catch (XmlPullParserException e) {
Log.e(TAG, "Error parsing the backup data: " + e);
} catch (IOException e) {
@@ -377,23 +226,22 @@ public class WifiBackupRestore {
* @param dataVersion version number parsed from incoming data.
* @return List<WifiConfiguration> object if parsing is successful, null otherwise.
*/
- private List<WifiConfiguration> parseWifiConfigurationsFromXml(
+ private List<WifiConfiguration> parseNetworkConfigurationsFromXml(
XmlPullParser in, int outerTagDepth, int dataVersion)
throws XmlPullParserException, IOException {
// Find the configuration list section.
if (!XmlUtil.gotoNextSection(
- in, XML_TAG_SECTION_HEADER_CONFIGURATION_LIST, outerTagDepth)) {
- Log.e(TAG, "Error parsing the backup data. Did not find configuration list");
+ in, XML_TAG_SECTION_HEADER_NETWORK_LIST, outerTagDepth)) {
+ Log.e(TAG, "Error parsing the backup data. Did not find network list");
// Malformed XML input, bail out.
return null;
}
// Find all the configurations within the configuration list section.
- int confListTagDepth = outerTagDepth + 1;
+ int networkListTagDepth = outerTagDepth + 1;
List<WifiConfiguration> configurations = new ArrayList<>();
- while (XmlUtil.gotoNextSection(
- in, XML_TAG_SECTION_HEADER_CONFIGURATION, confListTagDepth)) {
+ while (XmlUtil.gotoNextSection(in, XML_TAG_SECTION_HEADER_NETWORK, networkListTagDepth)) {
WifiConfiguration configuration =
- parseWifiConfigurationFromXml(in, dataVersion, confListTagDepth);
+ parseNetworkConfigurationFromXml(in, dataVersion, networkListTagDepth);
if (configuration != null) {
Log.v(TAG, "Parsed Configuration: " + configuration.configKey());
configurations.add(configuration);
@@ -403,21 +251,6 @@ public class WifiBackupRestore {
}
/**
- * Parse WepKeys from the XML stream.
- * Populate wepKeys array only if they were present in the backup data.
- */
- private void parseWepKeysFromXml(XmlPullParser in, String[] wepKeys)
- throws XmlPullParserException, IOException {
- String[] wepKeysInData =
- (String[]) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_WEP_KEYS);
- if (wepKeysInData != null) {
- for (int i = 0; i < wepKeys.length; i++) {
- wepKeys[i] = wepKeysInData[i];
- }
- }
- }
-
- /**
* Parses the configuration data elements from the provided XML stream to a Configuration.
*
* @param in XmlPullParser instance pointing to the XML stream.
@@ -425,53 +258,29 @@ public class WifiBackupRestore {
* @param dataVersion version number parsed from incoming data.
* @return WifiConfiguration object if parsing is successful, null otherwise.
*/
- private WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in, int dataVersion,
+ private WifiConfiguration parseNetworkConfigurationFromXml(XmlPullParser in, int dataVersion,
int outerTagDepth)
throws XmlPullParserException, IOException {
-
// Any version migration needs to be handled here in future.
if (dataVersion == INITIAL_BACKUP_DATA_VERSION) {
- WifiConfiguration configuration = new WifiConfiguration();
- String configKeyInData =
- (String) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_CONFIG_KEY);
- configuration.SSID =
- (String) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_SSID);
- configuration.BSSID =
- (String) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_BSSID);
- configuration.preSharedKey =
- (String) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_PRE_SHARED_KEY);
- parseWepKeysFromXml(in, configuration.wepKeys);
- configuration.wepTxKeyIndex =
- (int) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_WEP_TX_KEY_INDEX);
- configuration.hiddenSSID =
- (boolean) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_HIDDEN_SSID);
- byte[] allowedKeyMgmt =
- (byte[]) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_ALLOWED_KEY_MGMT);
- configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
- byte[] allowedProtocols =
- (byte[]) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_ALLOWED_PROTOCOLS);
- configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
- byte[] allowedAuthAlgorithms =
- (byte[]) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_ALLOWED_AUTH_ALGOS);
- configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
- configuration.shared =
- (boolean) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_SHARED);
- configuration.creatorUid =
- (int) XmlUtil.readNextValue(in, XML_TAG_CONFIGURATION_CREATOR_UID);
-
- // We should not have all the data to calculate the configKey. Compare it against the
- // configKey stored in the XML data.
- String configKeyCalculated = configuration.configKey();
- if (!configKeyInData.equals(configKeyCalculated)) {
- Log.e(TAG, "Configuration key does not match. Retrieved: " + configKeyInData
- + ", Calculated: " + configKeyCalculated);
- return null;
+ WifiConfiguration configuration = null;
+ int networkTagDepth = outerTagDepth + 1;
+ // Retrieve WifiConfiguration object first.
+ if (XmlUtil.gotoNextSection(
+ in, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION, networkTagDepth)) {
+ int configTagDepth = networkTagDepth + 1;
+ configuration =
+ WifiConfigurationXmlUtil.parseWifiConfigurationFromXml(in, configTagDepth);
+ if (configuration == null) {
+ return null;
+ }
}
// Now retrieve any IP configuration info if present.
- int confTagDepth = outerTagDepth + 1;
if (XmlUtil.gotoNextSection(
- in, XML_TAG_SECTION_HEADER_IP_CONFIGURATION, confTagDepth)) {
- IpConfiguration ipConfiguration = parseIpConfigurationFromXml(in, dataVersion);
+ in, XML_TAG_SECTION_HEADER_IP_CONFIGURATION, networkTagDepth)) {
+ int configTagDepth = networkTagDepth + 1;
+ IpConfiguration ipConfiguration =
+ IpConfigurationXmlUtil.parseIpConfigurationFromXml(in, configTagDepth);
configuration.setIpConfiguration(ipConfiguration);
}
return configuration;
@@ -480,120 +289,6 @@ public class WifiBackupRestore {
}
/**
- * Parse out the static IP configuration from the XML stream.
- */
- private StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
- throws XmlPullParserException, IOException {
-
- StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
- String linkAddressString =
- (String) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_LINK_ADDRESS);
- Integer linkPrefixLength =
- (Integer) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_LINK_PREFIX_LENGTH);
- if (linkAddressString != null && linkPrefixLength != null) {
- LinkAddress linkAddress = new LinkAddress(
- NetworkUtils.numericToInetAddress(linkAddressString),
- linkPrefixLength);
- if (linkAddress.getAddress() instanceof Inet4Address) {
- staticIpConfiguration.ipAddress = linkAddress;
- } else {
- Log.w(TAG, "Non-IPv4 address: " + linkAddress);
- }
- }
- String gatewayAddressString =
- (String) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_GATEWAY_ADDRESS);
- if (gatewayAddressString != null) {
- LinkAddress dest = null;
- InetAddress gateway =
- NetworkUtils.numericToInetAddress(gatewayAddressString);
- RouteInfo route = new RouteInfo(dest, gateway);
- if (route.isIPv4Default()) {
- staticIpConfiguration.gateway = gateway;
- } else {
- Log.w(TAG, "Non-IPv4 default route: " + route);
- }
- }
- String[] dnsServerAddressesString =
- (String[]) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_DNS_SERVER_ADDRESSES);
- if (dnsServerAddressesString != null) {
- for (String dnsServerAddressString : dnsServerAddressesString) {
- InetAddress dnsServerAddress =
- NetworkUtils.numericToInetAddress(dnsServerAddressString);
- staticIpConfiguration.dnsServers.add(dnsServerAddress);
- }
- }
- return staticIpConfiguration;
- }
-
- /**
- * Parses the IP configuration data elements from the provided XML stream to a IpConfiguration.
- *
- * @param in XmlPullParser instance pointing to the XML stream.
- * @param dataVersion version number parsed from incoming data.
- * @return IpConfiguration object if parsing is successful, null otherwise.
- */
- private IpConfiguration parseIpConfigurationFromXml(XmlPullParser in, int dataVersion)
- throws XmlPullParserException, IOException {
-
- // Any version migration needs to be handled here in future.
- if (dataVersion == INITIAL_BACKUP_DATA_VERSION) {
- IpConfiguration ipConfiguration = new IpConfiguration();
-
- // Parse out the IP assignment info first.
- String ipAssignmentString =
- (String) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_IP_ASSIGNMENT);
- IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
- ipConfiguration.setIpAssignment(ipAssignment);
- switch (ipAssignment) {
- case STATIC:
- StaticIpConfiguration staticIpConfiguration =
- parseStaticIpConfigurationFromXml(in);
- ipConfiguration.setStaticIpConfiguration(staticIpConfiguration);
- break;
- case DHCP:
- case UNASSIGNED:
- break;
- default:
- Log.wtf(TAG, "Unknown ip assignment type: " + ipAssignment);
- return null;
- }
-
- // Parse out the proxy settings next.
- String proxySettingsString =
- (String) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_PROXY_SETTINGS);
- ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
- ipConfiguration.setProxySettings(proxySettings);
- switch (proxySettings) {
- case STATIC:
- String proxyHost =
- (String) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_PROXY_HOST);
- int proxyPort =
- (int) XmlUtil.readNextValue(in, XML_TAG_IP_CONFIGURATION_PROXY_PORT);
- String proxyExclusionList =
- (String) XmlUtil.readNextValue(in,
- XML_TAG_IP_CONFIGURATION_PROXY_EXCLUSION_LIST);
- ipConfiguration.setHttpProxy(
- new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
- break;
- case PAC:
- String proxyPacFile =
- (String) XmlUtil.readNextValue(in,
- XML_TAG_IP_CONFIGURATION_PROXY_PAC_FILE);
- ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
- break;
- case NONE:
- case UNASSIGNED:
- break;
- default:
- Log.wtf(TAG, "Unknown proxy settings type: " + proxySettings);
- return null;
- }
- return ipConfiguration;
- }
- return null;
- }
-
- /**
* Create log dump of the backup data in XML format with the preShared
* key masked.
*/
@@ -711,7 +406,6 @@ public class WifiBackupRestore {
* List of keys to look out for in wpa_supplicant.conf parsing.
* These key values are declared in different parts of the wifi codebase today.
*/
- @VisibleForTesting
public static final String SUPPLICANT_KEY_SSID = WifiConfiguration.ssidVarName;
public static final String SUPPLICANT_KEY_HIDDEN = WifiConfiguration.hiddenSSIDVarName;
public static final String SUPPLICANT_KEY_KEY_MGMT = WifiConfiguration.KeyMgmt.varName;
@@ -735,6 +429,22 @@ public class WifiBackupRestore {
private static final String PASSWORD_MASK_REPLACE_PATTERN = "$1*";
/**
+ * Create log dump of the backup data in wpa_supplicant.conf format with the preShared
+ * key masked.
+ */
+ public static String createLogFromBackupData(byte[] data) {
+ String supplicantConfString;
+ try {
+ supplicantConfString = new String(data, StandardCharsets.UTF_8.name());
+ supplicantConfString = supplicantConfString.replaceAll(
+ PASSWORD_MASK_SEARCH_PATTERN, PASSWORD_MASK_REPLACE_PATTERN);
+ } catch (UnsupportedEncodingException e) {
+ return "";
+ }
+ return supplicantConfString;
+ }
+
+ /**
* Class for capturing a network definition from the wifi supplicant config file.
*/
static class SupplicantNetwork {
@@ -944,21 +654,5 @@ public class WifiBackupRestore {
return wifiConfigurations;
}
}
-
- /**
- * Create log dump of the backup data in wpa_supplicant.conf format with the preShared
- * key masked.
- */
- public static String createLogFromBackupData(byte[] data) {
- String supplicantConfString;
- try {
- supplicantConfString = new String(data, StandardCharsets.UTF_8.name());
- supplicantConfString = supplicantConfString.replaceAll(
- PASSWORD_MASK_SEARCH_PATTERN, PASSWORD_MASK_REPLACE_PATTERN);
- } catch (UnsupportedEncodingException e) {
- return "";
- }
- return supplicantConfString;
- }
}
}
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 9073959e7..214450c6e 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -16,6 +16,17 @@
package com.android.server.wifi.util;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.ProxyInfo;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.util.Log;
+
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -23,11 +34,13 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.BitSet;
/**
* Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
* The utility provides methods to write/parse section headers and write/parse values.
- *
* This utility is designed for formatting the XML into the following format:
* <Document Header>
* <Section 1 Header>
@@ -46,11 +59,29 @@ public class XmlUtil {
private static final String TAG = "WifiXmlUtil";
/**
- * Move the XML stream to the start of the next tag or the end of document.
+ * Ensure that the XML stream is at a start tag or the end of document.
+ *
+ * @throws {XmlPullParserException}, if parsing errors occur.
*/
- private static void gotoNextElement(XmlPullParser in)
+ private static void gotoStartTag(XmlPullParser in)
throws XmlPullParserException, IOException {
- XmlUtils.nextElement(in);
+ int type = in.getEventType();
+ while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
+ type = in.next();
+ }
+ }
+
+ /**
+ * Ensure that the XML stream is at an end tag or the end of document.
+ *
+ * @throws {XmlPullParserException}, if parsing errors occur.
+ */
+ private static void gotoEndTag(XmlPullParser in)
+ throws XmlPullParserException, IOException {
+ int type = in.getEventType();
+ while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
+ type = in.next();
+ }
}
/**
@@ -58,6 +89,7 @@ public class XmlUtil {
*
* @param in XmlPullParser instance pointing to the XML stream.
* @param headerName expected name for the start tag.
+ * @throws {XmlPullParserException}, if parsing errors occur.
*/
public static void gotoDocumentStart(XmlPullParser in, String headerName)
throws XmlPullParserException, IOException {
@@ -65,13 +97,14 @@ public class XmlUtil {
}
/**
- * Move the XML stream to the next section header. The provided outerdepth is used to find
- * sub sections within the provided depth.
+ * Move the XML stream to the next section header. The provided outerDepth is used to find
+ * sub sections within that depth.
*
* @param in XmlPullParser instance pointing to the XML stream.
* @param headerName expected name for the start tag.
* @param outerDepth Find section within this depth.
* @return {@code true} if a start tag with the provided name is found, {@code false} otherwise
+ * @throws {XmlPullParserException}, if parsing errors occur.
*/
public static boolean gotoNextSection(XmlPullParser in, String headerName, int outerDepth)
throws XmlPullParserException, IOException {
@@ -84,8 +117,49 @@ public class XmlUtil {
}
/**
+ * Checks if the stream is at the end of a section of values. This moves the stream to next tag
+ * and checks if it finds an end tag at the specified depth.
+ *
+ * @param in XmlPullParser instance pointing to the XML stream.
+ * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
+ * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
+ * @throws {XmlPullParserException}, if parsing errors occur.
+ */
+ public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
+ throws XmlPullParserException, IOException {
+ if (in.nextTag() == XmlPullParser.END_TAG && in.getDepth() == sectionDepth) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Read the current value in the XML stream using core XmlUtils and stores the retrieved
+ * value name in the string provided. This method reads the value contained in current start
+ * tag.
+ * Note: Because there could be genuine null values being read from the XML, this method raises
+ * an exception to indicate errors.
+ *
+ * @param in XmlPullParser instance pointing to the XML stream.
+ * @param valueName An array of one string, used to return the name attribute
+ * of the value's tag.
+ * @return value retrieved from the XML stream.
+ * @throws {XmlPullParserException}, if parsing errors occur.
+ */
+ public static Object readCurrentValue(XmlPullParser in, String[] valueName)
+ throws XmlPullParserException, IOException {
+ Object value = XmlUtils.readValueXml(in, valueName);
+ // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
+ // it to the end tag before returning from here.
+ gotoEndTag(in);
+ return value;
+ }
+
+ /**
* Read the next value in the XML stream using core XmlUtils and ensure that it matches the
- * provided name.
+ * provided name. This method moves the stream to the next start tag and reads the value
+ * contained in it.
* Note: Because there could be genuine null values being read from the XML, this method raises
* an exception to indicate errors.
*
@@ -94,23 +168,16 @@ public class XmlUtil {
* @throws {XmlPullParserException}, if the value read does not match |expectedName|,
* or if parsing errors occur.
*/
- public static Object readNextValue(XmlPullParser in, String expectedName)
+ public static Object readNextValueWithName(XmlPullParser in, String expectedName)
throws XmlPullParserException, IOException {
- String[] names = new String[1];
- names[0] = new String();
- gotoNextElement(in);
- Object value = XmlUtils.readValueXml(in, names);
- if (names[0].equals(expectedName)) {
- // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
- // it to the end before returning from here.
- while (in.getEventType() != XmlPullParser.END_DOCUMENT
- && in.getEventType() != XmlPullParser.END_TAG) {
- in.next();
- }
+ String[] valueName = new String[1];
+ XmlUtils.nextElement(in);
+ Object value = readCurrentValue(in, valueName);
+ if (valueName[0].equals(expectedName)) {
return value;
}
throw new XmlPullParserException(
- "Value not found. Expected: " + expectedName + ", but got: " + names[0]);
+ "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
}
/**
@@ -120,7 +187,7 @@ public class XmlUtil {
* @param headerName name for the start tag.
*/
public static void writeDocumentStart(XmlSerializer out, String headerName)
- throws XmlPullParserException, IOException {
+ throws IOException {
out.startDocument(null, true);
out.startTag(null, headerName);
}
@@ -132,7 +199,7 @@ public class XmlUtil {
* @param headerName name for the end tag.
*/
public static void writeDocumentEnd(XmlSerializer out, String headerName)
- throws XmlPullParserException, IOException {
+ throws IOException {
out.endTag(null, headerName);
out.endDocument();
}
@@ -144,7 +211,7 @@ public class XmlUtil {
* @param headerName name for the start tag.
*/
public static void writeNextSectionStart(XmlSerializer out, String headerName)
- throws XmlPullParserException, IOException {
+ throws IOException {
out.startTag(null, headerName);
}
@@ -155,7 +222,7 @@ public class XmlUtil {
* @param headerName name for the end tag.
*/
public static void writeNextSectionEnd(XmlSerializer out, String headerName)
- throws XmlPullParserException, IOException {
+ throws IOException {
out.endTag(null, headerName);
}
@@ -170,5 +237,412 @@ public class XmlUtil {
throws XmlPullParserException, IOException {
XmlUtils.writeValueXml(value, name, out);
}
+
+ /**
+ * Utility class to serialize and deseriaize WifConfiguration object to XML & vice versa.
+ * This is used by both #com.android.server.wifi.WifiConfigStore &
+ * #com.android.server.wifi.WifiBackupRestore modules.
+ * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
+ * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
+ * The parse method is written so that any element added/deleted in future revisions can
+ * be easily handled.
+ */
+ public static class WifiConfigurationXmlUtil {
+ /**
+ * List of XML tags corresponding to WifiConfiguration object elements.
+ */
+ public static final String XML_TAG_SSID = "SSID";
+ public static final String XML_TAG_BSSID = "BSSID";
+ public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
+ public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
+ public static final String XML_TAG_WEP_KEYS = "WEPKeys";
+ public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
+ public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
+ public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
+ public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
+ public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
+ public static final String XML_TAG_SHARED = "Shared";
+ public static final String XML_TAG_CREATOR_UID = "CreatorUid";
+
+ /**
+ * Write WepKeys to the XML stream.
+ * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
+ * are null. XmlUtils serialization doesn't handle this array of nulls well .
+ * So, write null if the keys are not initialized.
+ */
+ private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
+ throws XmlPullParserException, IOException {
+ if (wepKeys[0] != null) {
+ XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeys);
+ } else {
+ XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
+ }
+ }
+
+ /**
+ * Write the Configuration data elements that are common for backup & config store to the
+ * XML stream.
+ *
+ * @param out XmlSerializer instance pointing to the XML stream.
+ * @param configuration WifiConfiguration object to be serialized.
+ */
+ public static void writeCommonWifiConfigurationElementsToXml(XmlSerializer out,
+ WifiConfiguration configuration)
+ throws XmlPullParserException, IOException {
+ XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
+ XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
+ XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
+ XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
+ writeWepKeysToXml(out, configuration.wepKeys);
+ XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
+ XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
+ XmlUtil.writeNextValue(
+ out, XML_TAG_ALLOWED_KEY_MGMT,
+ configuration.allowedKeyManagement.toByteArray());
+ XmlUtil.writeNextValue(
+ out, XML_TAG_ALLOWED_PROTOCOLS,
+ configuration.allowedProtocols.toByteArray());
+ XmlUtil.writeNextValue(
+ out, XML_TAG_ALLOWED_AUTH_ALGOS,
+ configuration.allowedAuthAlgorithms.toByteArray());
+ XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
+ XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
+ }
+
+ /**
+ * Write the Configuration data elements for backup from the provided Configuration to the
+ * XML stream.
+ * Note: This is a subset of the elements serialized for config store.
+ *
+ * @param out XmlSerializer instance pointing to the XML stream.
+ * @param configuration WifiConfiguration object to be serialized.
+ */
+ public static void writeWifiConfigurationToXmlForBackup(XmlSerializer out,
+ WifiConfiguration configuration)
+ throws XmlPullParserException, IOException {
+ writeCommonWifiConfigurationElementsToXml(out, configuration);
+ }
+
+ /**
+ * Write the Configuration data elements for config store from the provided Configuration
+ * to the XML stream.
+ */
+ public static void writeWifiConfigurationToXmlForConfigStore(XmlSerializer out,
+ WifiConfiguration configuration)
+ throws XmlPullParserException, IOException {
+ writeCommonWifiConfigurationElementsToXml(out, configuration);
+ // TODO: Will need to add more elements which needs to be persisted.
+ }
+
+ /**
+ * Populate wepKeys array only if they were non-null in the backup data.
+ */
+ private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
+ throws XmlPullParserException, IOException {
+ String[] wepKeysInData = (String[]) value;
+ if (wepKeysInData != null) {
+ for (int i = 0; i < wepKeys.length; i++) {
+ wepKeys[i] = wepKeysInData[i];
+ }
+ }
+ }
+
+ /**
+ * Parses the configuration data elements from the provided XML stream to a Configuration.
+ * Note: This is used for parsing both backup data and config store data. Looping through
+ * the tags make it easy to add or remove elements in the future versions if needed.
+ *
+ * @param in XmlPullParser instance pointing to the XML stream.
+ * @param outerTagDepth depth of the outer tag in the XML document.
+ * @return WifiConfiguration object if parsing is successful, null otherwise.
+ */
+ public static WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in,
+ int outerTagDepth)
+ throws XmlPullParserException, IOException {
+ WifiConfiguration configuration = new WifiConfiguration();
+ String configKeyInData = null;
+
+ // Loop through and parse out all the elements from the stream within this section.
+ while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (valueName[0] == null) {
+ Log.e(TAG, "Missing value name");
+ return null;
+ }
+ switch (valueName[0]) {
+ case XML_TAG_CONFIG_KEY:
+ configKeyInData = (String) value;
+ break;
+ case XML_TAG_SSID:
+ configuration.SSID = (String) value;
+ break;
+ case XML_TAG_BSSID:
+ configuration.BSSID = (String) value;
+ break;
+ case XML_TAG_PRE_SHARED_KEY:
+ configuration.preSharedKey = (String) value;
+ break;
+ case XML_TAG_WEP_KEYS:
+ populateWepKeysFromXmlValue(value, configuration.wepKeys);
+ break;
+ case XML_TAG_WEP_TX_KEY_INDEX:
+ configuration.wepTxKeyIndex = (int) value;
+ break;
+ case XML_TAG_HIDDEN_SSID:
+ configuration.hiddenSSID = (boolean) value;
+ break;
+ case XML_TAG_ALLOWED_KEY_MGMT:
+ byte[] allowedKeyMgmt = (byte[]) value;
+ configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
+ break;
+ case XML_TAG_ALLOWED_PROTOCOLS:
+ byte[] allowedProtocols = (byte[]) value;
+ configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
+ break;
+ case XML_TAG_ALLOWED_AUTH_ALGOS:
+ byte[] allowedAuthAlgorithms = (byte[]) value;
+ configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
+ break;
+ case XML_TAG_SHARED:
+ configuration.shared = (boolean) value;
+ break;
+ case XML_TAG_CREATOR_UID:
+ configuration.creatorUid = (int) value;
+ break;
+ default:
+ Log.e(TAG, "Unknown value name found: " + valueName[0]);
+ return null;
+ }
+ }
+ // We should now have all the data to calculate the configKey. Compare it against the
+ // configKey stored in the XML data.
+ String configKeyCalculated = configuration.configKey();
+ if (configKeyInData == null || !configKeyInData.equals(configKeyCalculated)) {
+ Log.e(TAG, "Configuration key does not match. Retrieved: " + configKeyInData
+ + ", Calculated: " + configKeyCalculated);
+ return null;
+ }
+ return configuration;
+ }
+ }
+
+ /**
+ * Utility class to serialize and deseriaize IpConfiguration object to XML & vice versa.
+ * This is used by both #com.android.server.wifi.WifiConfigStore &
+ * #com.android.server.wifi.WifiBackupRestore modules.
+ */
+ public static class IpConfigurationXmlUtil {
+
+ /**
+ * List of XML tags corresponding to IpConfiguration object elements.
+ */
+ public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
+ public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
+ public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
+ public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
+ public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
+ public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
+ public static final String XML_TAG_PROXY_HOST = "ProxyHost";
+ public static final String XML_TAG_PROXY_PORT = "ProxyPort";
+ public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
+ public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
+
+ /**
+ * Write the static IP configuration data elements to XML stream.
+ */
+ private static void writeStaticIpConfigurationToXml(XmlSerializer out,
+ StaticIpConfiguration staticIpConfiguration)
+ throws XmlPullParserException, IOException {
+ if (staticIpConfiguration.ipAddress != null) {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_LINK_ADDRESS,
+ staticIpConfiguration.ipAddress.getAddress().getHostAddress());
+ XmlUtil.writeNextValue(
+ out, XML_TAG_LINK_PREFIX_LENGTH,
+ staticIpConfiguration.ipAddress.getPrefixLength());
+ } else {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_LINK_ADDRESS, null);
+ XmlUtil.writeNextValue(
+ out, XML_TAG_LINK_PREFIX_LENGTH, null);
+ }
+ if (staticIpConfiguration.gateway != null) {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_GATEWAY_ADDRESS,
+ staticIpConfiguration.gateway.getHostAddress());
+ } else {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_GATEWAY_ADDRESS, null);
+
+ }
+ if (staticIpConfiguration.dnsServers != null) {
+ // Create a string array of DNS server addresses
+ String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
+ int dnsServerIdx = 0;
+ for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
+ dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
+ }
+ XmlUtil.writeNextValue(
+ out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
+ } else {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_DNS_SERVER_ADDRESSES, null);
+ }
+ }
+
+ /**
+ * Write the IP configuration data elements from the provided Configuration to the XML
+ * stream.
+ */
+ public static void writeIpConfigurationToXml(XmlSerializer out,
+ IpConfiguration ipConfiguration)
+ throws XmlPullParserException, IOException {
+ // Write IP assignment settings
+ XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
+ ipConfiguration.ipAssignment.toString());
+ switch (ipConfiguration.ipAssignment) {
+ case STATIC:
+ writeStaticIpConfigurationToXml(
+ out, ipConfiguration.getStaticIpConfiguration());
+ break;
+ default:
+ break;
+ }
+
+ // Write proxy settings
+ XmlUtil.writeNextValue(
+ out, XML_TAG_PROXY_SETTINGS,
+ ipConfiguration.proxySettings.toString());
+ switch (ipConfiguration.proxySettings) {
+ case STATIC:
+ XmlUtil.writeNextValue(
+ out, XML_TAG_PROXY_HOST,
+ ipConfiguration.httpProxy.getHost());
+ XmlUtil.writeNextValue(
+ out, XML_TAG_PROXY_PORT,
+ ipConfiguration.httpProxy.getPort());
+ XmlUtil.writeNextValue(
+ out, XML_TAG_PROXY_EXCLUSION_LIST,
+ ipConfiguration.httpProxy.getExclusionListAsString());
+ break;
+ case PAC:
+ XmlUtil.writeNextValue(
+ out, XML_TAG_PROXY_PAC_FILE,
+ ipConfiguration.httpProxy.getPacFileUrl().toString());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Parse out the static IP configuration from the XML stream.
+ */
+ private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
+ throws XmlPullParserException, IOException {
+ StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+
+ String linkAddressString =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
+ Integer linkPrefixLength =
+ (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
+ if (linkAddressString != null && linkPrefixLength != null) {
+ LinkAddress linkAddress = new LinkAddress(
+ NetworkUtils.numericToInetAddress(linkAddressString),
+ linkPrefixLength);
+ if (linkAddress.getAddress() instanceof Inet4Address) {
+ staticIpConfiguration.ipAddress = linkAddress;
+ } else {
+ Log.w(TAG, "Non-IPv4 address: " + linkAddress);
+ }
+ }
+ String gatewayAddressString =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
+ if (gatewayAddressString != null) {
+ LinkAddress dest = null;
+ InetAddress gateway =
+ NetworkUtils.numericToInetAddress(gatewayAddressString);
+ RouteInfo route = new RouteInfo(dest, gateway);
+ if (route.isIPv4Default()) {
+ staticIpConfiguration.gateway = gateway;
+ } else {
+ Log.w(TAG, "Non-IPv4 default route: " + route);
+ }
+ }
+ String[] dnsServerAddressesString =
+ (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
+ if (dnsServerAddressesString != null) {
+ for (String dnsServerAddressString : dnsServerAddressesString) {
+ InetAddress dnsServerAddress =
+ NetworkUtils.numericToInetAddress(dnsServerAddressString);
+ staticIpConfiguration.dnsServers.add(dnsServerAddress);
+ }
+ }
+ return staticIpConfiguration;
+ }
+
+ /**
+ * Parses the IP configuration data elements from the provided XML stream to a
+ * IpConfiguration.
+ *
+ * @param in XmlPullParser instance pointing to the XML stream.
+ * @param outerTagDepth depth of the outer tag in the XML document.
+ * @return IpConfiguration object if parsing is successful, null otherwise.
+ */
+ public static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in,
+ int outerTagDepth)
+ throws XmlPullParserException, IOException {
+ IpConfiguration ipConfiguration = new IpConfiguration();
+
+ // Parse out the IP assignment info first.
+ String ipAssignmentString =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
+ IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
+ ipConfiguration.setIpAssignment(ipAssignment);
+ switch (ipAssignment) {
+ case STATIC:
+ ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
+ break;
+ case DHCP:
+ case UNASSIGNED:
+ break;
+ default:
+ Log.wtf(TAG, "Unknown ip assignment type: " + ipAssignment);
+ return null;
+ }
+
+ // Parse out the proxy settings next.
+ String proxySettingsString =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
+ ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
+ ipConfiguration.setProxySettings(proxySettings);
+ switch (proxySettings) {
+ case STATIC:
+ String proxyHost =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
+ int proxyPort =
+ (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
+ String proxyExclusionList =
+ (String) XmlUtil.readNextValueWithName(
+ in, XML_TAG_PROXY_EXCLUSION_LIST);
+ ipConfiguration.setHttpProxy(
+ new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
+ break;
+ case PAC:
+ String proxyPacFile =
+ (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
+ ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
+ break;
+ case NONE:
+ case UNASSIGNED:
+ break;
+ default:
+ Log.wtf(TAG, "Unknown proxy settings type: " + proxySettings);
+ return null;
+ }
+ return ipConfiguration;
+ }
+ }
}