XmlUtil.java revision 052b948a8b8a009486e35cb56dbd7bb9516e8626
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.util; 18 19import android.net.IpConfiguration; 20import android.net.IpConfiguration.IpAssignment; 21import android.net.IpConfiguration.ProxySettings; 22import android.net.LinkAddress; 23import android.net.NetworkUtils; 24import android.net.ProxyInfo; 25import android.net.RouteInfo; 26import android.net.StaticIpConfiguration; 27import android.net.wifi.WifiConfiguration; 28import android.util.Log; 29 30import com.android.internal.util.XmlUtils; 31 32import org.xmlpull.v1.XmlPullParser; 33import org.xmlpull.v1.XmlPullParserException; 34import org.xmlpull.v1.XmlSerializer; 35 36import java.io.IOException; 37import java.net.Inet4Address; 38import java.net.InetAddress; 39import java.util.BitSet; 40 41/** 42 * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core. 43 * The utility provides methods to write/parse section headers and write/parse values. 44 * This utility is designed for formatting the XML into the following format: 45 * <Document Header> 46 * <Section 1 Header> 47 * <Value 1> 48 * <Value 2> 49 * ... 50 * <Sub Section 1 Header> 51 * <Value 1> 52 * <Value 2> 53 * ... 54 * </Sub Section 1 Header> 55 * </Section 1 Header> 56 * </Document Header> 57 */ 58public class XmlUtil { 59 private static final String TAG = "WifiXmlUtil"; 60 61 /** 62 * Ensure that the XML stream is at a start tag or the end of document. 63 * 64 * @throws XmlPullParserException if parsing errors occur. 65 */ 66 private static void gotoStartTag(XmlPullParser in) 67 throws XmlPullParserException, IOException { 68 int type = in.getEventType(); 69 while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { 70 type = in.next(); 71 } 72 } 73 74 /** 75 * Ensure that the XML stream is at an end tag or the end of document. 76 * 77 * @throws XmlPullParserException if parsing errors occur. 78 */ 79 private static void gotoEndTag(XmlPullParser in) 80 throws XmlPullParserException, IOException { 81 int type = in.getEventType(); 82 while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) { 83 type = in.next(); 84 } 85 } 86 87 /** 88 * Start processing the XML stream at the document header. 89 * 90 * @param in XmlPullParser instance pointing to the XML stream. 91 * @param headerName expected name for the start tag. 92 * @throws XmlPullParserException if parsing errors occur. 93 */ 94 public static void gotoDocumentStart(XmlPullParser in, String headerName) 95 throws XmlPullParserException, IOException { 96 XmlUtils.beginDocument(in, headerName); 97 } 98 99 /** 100 * Move the XML stream to the next section header. The provided outerDepth is used to find 101 * sub sections within that depth. 102 * 103 * @param in XmlPullParser instance pointing to the XML stream. 104 * @param headerName expected name for the start tag. 105 * @param outerDepth Find section within this depth. 106 * @return {@code true} if a start tag with the provided name is found, {@code false} otherwise 107 * @throws XmlPullParserException if parsing errors occur. 108 */ 109 public static boolean gotoNextSection(XmlPullParser in, String headerName, int outerDepth) 110 throws XmlPullParserException, IOException { 111 while (XmlUtils.nextElementWithin(in, outerDepth)) { 112 if (in.getName().equals(headerName)) { 113 return true; 114 } 115 } 116 return false; 117 } 118 119 /** 120 * Checks if the stream is at the end of a section of values. This moves the stream to next tag 121 * and checks if it finds an end tag at the specified depth. 122 * 123 * @param in XmlPullParser instance pointing to the XML stream. 124 * @param sectionDepth depth of the start tag of this section. Used to match the end tag. 125 * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise 126 * @throws XmlPullParserException if parsing errors occur. 127 */ 128 public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth) 129 throws XmlPullParserException, IOException { 130 return (in.nextTag() == XmlPullParser.END_TAG && in.getDepth() == sectionDepth); 131 } 132 133 /** 134 * Read the current value in the XML stream using core XmlUtils and stores the retrieved 135 * value name in the string provided. This method reads the value contained in current start 136 * tag. 137 * Note: Because there could be genuine null values being read from the XML, this method raises 138 * an exception to indicate errors. 139 * 140 * @param in XmlPullParser instance pointing to the XML stream. 141 * @param valueName An array of one string, used to return the name attribute 142 * of the value's tag. 143 * @return value retrieved from the XML stream. 144 * @throws XmlPullParserException if parsing errors occur. 145 */ 146 public static Object readCurrentValue(XmlPullParser in, String[] valueName) 147 throws XmlPullParserException, IOException { 148 Object value = XmlUtils.readValueXml(in, valueName); 149 // XmlUtils.readValue does not always move the stream to the end of the tag. So, move 150 // it to the end tag before returning from here. 151 gotoEndTag(in); 152 return value; 153 } 154 155 /** 156 * Read the next value in the XML stream using core XmlUtils and ensure that it matches the 157 * provided name. This method moves the stream to the next start tag and reads the value 158 * contained in it. 159 * Note: Because there could be genuine null values being read from the XML, this method raises 160 * an exception to indicate errors. 161 * 162 * @param in XmlPullParser instance pointing to the XML stream. 163 * @return value retrieved from the XML stream. 164 * @throws XmlPullParserException if the value read does not match |expectedName|, 165 * or if parsing errors occur. 166 */ 167 public static Object readNextValueWithName(XmlPullParser in, String expectedName) 168 throws XmlPullParserException, IOException { 169 String[] valueName = new String[1]; 170 XmlUtils.nextElement(in); 171 Object value = readCurrentValue(in, valueName); 172 if (valueName[0].equals(expectedName)) { 173 return value; 174 } 175 throw new XmlPullParserException( 176 "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]); 177 } 178 179 /** 180 * Write the XML document start with the provided document header name. 181 * 182 * @param out XmlSerializer instance pointing to the XML stream. 183 * @param headerName name for the start tag. 184 */ 185 public static void writeDocumentStart(XmlSerializer out, String headerName) 186 throws IOException { 187 out.startDocument(null, true); 188 out.startTag(null, headerName); 189 } 190 191 /** 192 * Write the XML document end with the provided document header name. 193 * 194 * @param out XmlSerializer instance pointing to the XML stream. 195 * @param headerName name for the end tag. 196 */ 197 public static void writeDocumentEnd(XmlSerializer out, String headerName) 198 throws IOException { 199 out.endTag(null, headerName); 200 out.endDocument(); 201 } 202 203 /** 204 * Write a section start header tag with the provided section name. 205 * 206 * @param out XmlSerializer instance pointing to the XML stream. 207 * @param headerName name for the start tag. 208 */ 209 public static void writeNextSectionStart(XmlSerializer out, String headerName) 210 throws IOException { 211 out.startTag(null, headerName); 212 } 213 214 /** 215 * Write a section end header tag with the provided section name. 216 * 217 * @param out XmlSerializer instance pointing to the XML stream. 218 * @param headerName name for the end tag. 219 */ 220 public static void writeNextSectionEnd(XmlSerializer out, String headerName) 221 throws IOException { 222 out.endTag(null, headerName); 223 } 224 225 /** 226 * Write the value with the provided name in the XML stream using core XmlUtils. 227 * 228 * @param out XmlSerializer instance pointing to the XML stream. 229 * @param name name of the value. 230 * @param value value to be written. 231 */ 232 public static void writeNextValue(XmlSerializer out, String name, Object value) 233 throws XmlPullParserException, IOException { 234 XmlUtils.writeValueXml(value, name, out); 235 } 236 237 /** 238 * Utility class to serialize and deseriaize WifConfiguration object to XML & vice versa. 239 * This is used by both #com.android.server.wifi.WifiConfigStore & 240 * #com.android.server.wifi.WifiBackupRestore modules. 241 * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store. 242 * There is only 1 version of |parseXmlToConfiguration| for both backup & config store. 243 * The parse method is written so that any element added/deleted in future revisions can 244 * be easily handled. 245 */ 246 public static class WifiConfigurationXmlUtil { 247 /** 248 * List of XML tags corresponding to WifiConfiguration object elements. 249 */ 250 public static final String XML_TAG_SSID = "SSID"; 251 public static final String XML_TAG_BSSID = "BSSID"; 252 public static final String XML_TAG_CONFIG_KEY = "ConfigKey"; 253 public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey"; 254 public static final String XML_TAG_WEP_KEYS = "WEPKeys"; 255 public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex"; 256 public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID"; 257 public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt"; 258 public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols"; 259 public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos"; 260 public static final String XML_TAG_SHARED = "Shared"; 261 public static final String XML_TAG_CREATOR_UID = "CreatorUid"; 262 263 /** 264 * Write WepKeys to the XML stream. 265 * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements 266 * are null. XmlUtils serialization doesn't handle this array of nulls well . 267 * So, write null if the keys are not initialized. 268 */ 269 private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys) 270 throws XmlPullParserException, IOException { 271 if (wepKeys[0] != null) { 272 XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeys); 273 } else { 274 XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null); 275 } 276 } 277 278 /** 279 * Write the Configuration data elements that are common for backup & config store to the 280 * XML stream. 281 * 282 * @param out XmlSerializer instance pointing to the XML stream. 283 * @param configuration WifiConfiguration object to be serialized. 284 */ 285 public static void writeCommonWifiConfigurationElementsToXml(XmlSerializer out, 286 WifiConfiguration configuration) 287 throws XmlPullParserException, IOException { 288 XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey()); 289 XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID); 290 XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID); 291 XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey); 292 writeWepKeysToXml(out, configuration.wepKeys); 293 XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex); 294 XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID); 295 XmlUtil.writeNextValue( 296 out, XML_TAG_ALLOWED_KEY_MGMT, 297 configuration.allowedKeyManagement.toByteArray()); 298 XmlUtil.writeNextValue( 299 out, XML_TAG_ALLOWED_PROTOCOLS, 300 configuration.allowedProtocols.toByteArray()); 301 XmlUtil.writeNextValue( 302 out, XML_TAG_ALLOWED_AUTH_ALGOS, 303 configuration.allowedAuthAlgorithms.toByteArray()); 304 XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared); 305 XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid); 306 } 307 308 /** 309 * Write the Configuration data elements for backup from the provided Configuration to the 310 * XML stream. 311 * Note: This is a subset of the elements serialized for config store. 312 * 313 * @param out XmlSerializer instance pointing to the XML stream. 314 * @param configuration WifiConfiguration object to be serialized. 315 */ 316 public static void writeWifiConfigurationToXmlForBackup(XmlSerializer out, 317 WifiConfiguration configuration) 318 throws XmlPullParserException, IOException { 319 writeCommonWifiConfigurationElementsToXml(out, configuration); 320 } 321 322 /** 323 * Write the Configuration data elements for config store from the provided Configuration 324 * to the XML stream. 325 */ 326 public static void writeWifiConfigurationToXmlForConfigStore(XmlSerializer out, 327 WifiConfiguration configuration) 328 throws XmlPullParserException, IOException { 329 writeCommonWifiConfigurationElementsToXml(out, configuration); 330 // TODO: Will need to add more elements which needs to be persisted. 331 } 332 333 /** 334 * Populate wepKeys array only if they were non-null in the backup data. 335 */ 336 private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys) 337 throws XmlPullParserException, IOException { 338 String[] wepKeysInData = (String[]) value; 339 if (wepKeysInData != null) { 340 for (int i = 0; i < wepKeys.length; i++) { 341 wepKeys[i] = wepKeysInData[i]; 342 } 343 } 344 } 345 346 /** 347 * Parses the configuration data elements from the provided XML stream to a Configuration. 348 * Note: This is used for parsing both backup data and config store data. Looping through 349 * the tags make it easy to add or remove elements in the future versions if needed. 350 * 351 * @param in XmlPullParser instance pointing to the XML stream. 352 * @param outerTagDepth depth of the outer tag in the XML document. 353 * @return WifiConfiguration object if parsing is successful, null otherwise. 354 */ 355 public static WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in, 356 int outerTagDepth) 357 throws XmlPullParserException, IOException { 358 WifiConfiguration configuration = new WifiConfiguration(); 359 String configKeyInData = null; 360 361 // Loop through and parse out all the elements from the stream within this section. 362 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 363 String[] valueName = new String[1]; 364 Object value = XmlUtil.readCurrentValue(in, valueName); 365 if (valueName[0] == null) { 366 Log.e(TAG, "Missing value name"); 367 return null; 368 } 369 switch (valueName[0]) { 370 case XML_TAG_CONFIG_KEY: 371 configKeyInData = (String) value; 372 break; 373 case XML_TAG_SSID: 374 configuration.SSID = (String) value; 375 break; 376 case XML_TAG_BSSID: 377 configuration.BSSID = (String) value; 378 break; 379 case XML_TAG_PRE_SHARED_KEY: 380 configuration.preSharedKey = (String) value; 381 break; 382 case XML_TAG_WEP_KEYS: 383 populateWepKeysFromXmlValue(value, configuration.wepKeys); 384 break; 385 case XML_TAG_WEP_TX_KEY_INDEX: 386 configuration.wepTxKeyIndex = (int) value; 387 break; 388 case XML_TAG_HIDDEN_SSID: 389 configuration.hiddenSSID = (boolean) value; 390 break; 391 case XML_TAG_ALLOWED_KEY_MGMT: 392 byte[] allowedKeyMgmt = (byte[]) value; 393 configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt); 394 break; 395 case XML_TAG_ALLOWED_PROTOCOLS: 396 byte[] allowedProtocols = (byte[]) value; 397 configuration.allowedProtocols = BitSet.valueOf(allowedProtocols); 398 break; 399 case XML_TAG_ALLOWED_AUTH_ALGOS: 400 byte[] allowedAuthAlgorithms = (byte[]) value; 401 configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms); 402 break; 403 case XML_TAG_SHARED: 404 configuration.shared = (boolean) value; 405 break; 406 case XML_TAG_CREATOR_UID: 407 configuration.creatorUid = (int) value; 408 break; 409 default: 410 Log.e(TAG, "Unknown value name found: " + valueName[0]); 411 return null; 412 } 413 } 414 // We should now have all the data to calculate the configKey. Compare it against the 415 // configKey stored in the XML data. 416 String configKeyCalculated = configuration.configKey(); 417 if (configKeyInData == null || !configKeyInData.equals(configKeyCalculated)) { 418 Log.e(TAG, "Configuration key does not match. Retrieved: " + configKeyInData 419 + ", Calculated: " + configKeyCalculated); 420 return null; 421 } 422 return configuration; 423 } 424 } 425 426 /** 427 * Utility class to serialize and deseriaize IpConfiguration object to XML & vice versa. 428 * This is used by both #com.android.server.wifi.WifiConfigStore & 429 * #com.android.server.wifi.WifiBackupRestore modules. 430 */ 431 public static class IpConfigurationXmlUtil { 432 433 /** 434 * List of XML tags corresponding to IpConfiguration object elements. 435 */ 436 public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment"; 437 public static final String XML_TAG_LINK_ADDRESS = "LinkAddress"; 438 public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength"; 439 public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress"; 440 public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers"; 441 public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings"; 442 public static final String XML_TAG_PROXY_HOST = "ProxyHost"; 443 public static final String XML_TAG_PROXY_PORT = "ProxyPort"; 444 public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac"; 445 public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList"; 446 447 /** 448 * Write the static IP configuration data elements to XML stream. 449 */ 450 private static void writeStaticIpConfigurationToXml(XmlSerializer out, 451 StaticIpConfiguration staticIpConfiguration) 452 throws XmlPullParserException, IOException { 453 if (staticIpConfiguration.ipAddress != null) { 454 XmlUtil.writeNextValue( 455 out, XML_TAG_LINK_ADDRESS, 456 staticIpConfiguration.ipAddress.getAddress().getHostAddress()); 457 XmlUtil.writeNextValue( 458 out, XML_TAG_LINK_PREFIX_LENGTH, 459 staticIpConfiguration.ipAddress.getPrefixLength()); 460 } else { 461 XmlUtil.writeNextValue( 462 out, XML_TAG_LINK_ADDRESS, null); 463 XmlUtil.writeNextValue( 464 out, XML_TAG_LINK_PREFIX_LENGTH, null); 465 } 466 if (staticIpConfiguration.gateway != null) { 467 XmlUtil.writeNextValue( 468 out, XML_TAG_GATEWAY_ADDRESS, 469 staticIpConfiguration.gateway.getHostAddress()); 470 } else { 471 XmlUtil.writeNextValue( 472 out, XML_TAG_GATEWAY_ADDRESS, null); 473 474 } 475 if (staticIpConfiguration.dnsServers != null) { 476 // Create a string array of DNS server addresses 477 String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()]; 478 int dnsServerIdx = 0; 479 for (InetAddress inetAddr : staticIpConfiguration.dnsServers) { 480 dnsServers[dnsServerIdx++] = inetAddr.getHostAddress(); 481 } 482 XmlUtil.writeNextValue( 483 out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers); 484 } else { 485 XmlUtil.writeNextValue( 486 out, XML_TAG_DNS_SERVER_ADDRESSES, null); 487 } 488 } 489 490 /** 491 * Write the IP configuration data elements from the provided Configuration to the XML 492 * stream. 493 */ 494 public static void writeIpConfigurationToXml(XmlSerializer out, 495 IpConfiguration ipConfiguration) 496 throws XmlPullParserException, IOException { 497 // Write IP assignment settings 498 XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT, 499 ipConfiguration.ipAssignment.toString()); 500 switch (ipConfiguration.ipAssignment) { 501 case STATIC: 502 writeStaticIpConfigurationToXml( 503 out, ipConfiguration.getStaticIpConfiguration()); 504 break; 505 default: 506 break; 507 } 508 509 // Write proxy settings 510 XmlUtil.writeNextValue( 511 out, XML_TAG_PROXY_SETTINGS, 512 ipConfiguration.proxySettings.toString()); 513 switch (ipConfiguration.proxySettings) { 514 case STATIC: 515 XmlUtil.writeNextValue( 516 out, XML_TAG_PROXY_HOST, 517 ipConfiguration.httpProxy.getHost()); 518 XmlUtil.writeNextValue( 519 out, XML_TAG_PROXY_PORT, 520 ipConfiguration.httpProxy.getPort()); 521 XmlUtil.writeNextValue( 522 out, XML_TAG_PROXY_EXCLUSION_LIST, 523 ipConfiguration.httpProxy.getExclusionListAsString()); 524 break; 525 case PAC: 526 XmlUtil.writeNextValue( 527 out, XML_TAG_PROXY_PAC_FILE, 528 ipConfiguration.httpProxy.getPacFileUrl().toString()); 529 break; 530 default: 531 break; 532 } 533 } 534 535 /** 536 * Parse out the static IP configuration from the XML stream. 537 */ 538 private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in) 539 throws XmlPullParserException, IOException { 540 StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); 541 542 String linkAddressString = 543 (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS); 544 Integer linkPrefixLength = 545 (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH); 546 if (linkAddressString != null && linkPrefixLength != null) { 547 LinkAddress linkAddress = new LinkAddress( 548 NetworkUtils.numericToInetAddress(linkAddressString), 549 linkPrefixLength); 550 if (linkAddress.getAddress() instanceof Inet4Address) { 551 staticIpConfiguration.ipAddress = linkAddress; 552 } else { 553 Log.w(TAG, "Non-IPv4 address: " + linkAddress); 554 } 555 } 556 String gatewayAddressString = 557 (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS); 558 if (gatewayAddressString != null) { 559 LinkAddress dest = null; 560 InetAddress gateway = 561 NetworkUtils.numericToInetAddress(gatewayAddressString); 562 RouteInfo route = new RouteInfo(dest, gateway); 563 if (route.isIPv4Default()) { 564 staticIpConfiguration.gateway = gateway; 565 } else { 566 Log.w(TAG, "Non-IPv4 default route: " + route); 567 } 568 } 569 String[] dnsServerAddressesString = 570 (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES); 571 if (dnsServerAddressesString != null) { 572 for (String dnsServerAddressString : dnsServerAddressesString) { 573 InetAddress dnsServerAddress = 574 NetworkUtils.numericToInetAddress(dnsServerAddressString); 575 staticIpConfiguration.dnsServers.add(dnsServerAddress); 576 } 577 } 578 return staticIpConfiguration; 579 } 580 581 /** 582 * Parses the IP configuration data elements from the provided XML stream to a 583 * IpConfiguration. 584 * 585 * @param in XmlPullParser instance pointing to the XML stream. 586 * @param outerTagDepth depth of the outer tag in the XML document. 587 * @return IpConfiguration object if parsing is successful, null otherwise. 588 */ 589 public static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in, 590 int outerTagDepth) 591 throws XmlPullParserException, IOException { 592 IpConfiguration ipConfiguration = new IpConfiguration(); 593 594 // Parse out the IP assignment info first. 595 String ipAssignmentString = 596 (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT); 597 IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString); 598 ipConfiguration.setIpAssignment(ipAssignment); 599 switch (ipAssignment) { 600 case STATIC: 601 ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in)); 602 break; 603 case DHCP: 604 case UNASSIGNED: 605 break; 606 default: 607 Log.wtf(TAG, "Unknown ip assignment type: " + ipAssignment); 608 return null; 609 } 610 611 // Parse out the proxy settings next. 612 String proxySettingsString = 613 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS); 614 ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString); 615 ipConfiguration.setProxySettings(proxySettings); 616 switch (proxySettings) { 617 case STATIC: 618 String proxyHost = 619 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST); 620 int proxyPort = 621 (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT); 622 String proxyExclusionList = 623 (String) XmlUtil.readNextValueWithName( 624 in, XML_TAG_PROXY_EXCLUSION_LIST); 625 ipConfiguration.setHttpProxy( 626 new ProxyInfo(proxyHost, proxyPort, proxyExclusionList)); 627 break; 628 case PAC: 629 String proxyPacFile = 630 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE); 631 ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile)); 632 break; 633 case NONE: 634 case UNASSIGNED: 635 break; 636 default: 637 Log.wtf(TAG, "Unknown proxy settings type: " + proxySettings); 638 return null; 639 } 640 return ipConfiguration; 641 } 642 } 643} 644 645