XmlUtil.java revision 06a2281303248446bacc87a00ab66ea1fdf0392d
12b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/*
22b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Copyright (C) 2016 The Android Open Source Project
32b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
42b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Licensed under the Apache License, Version 2.0 (the "License");
52b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * you may not use this file except in compliance with the License.
62b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * You may obtain a copy of the License at
72b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
82b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *      http://www.apache.org/licenses/LICENSE-2.0
92b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Unless required by applicable law or agreed to in writing, software
112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * distributed under the License is distributed on an "AS IS" BASIS,
122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * See the License for the specific language governing permissions and
142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * limitations under the License.
152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspackage com.android.server.wifi.util;
182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
19e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration;
20e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.IpAssignment;
21e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.ProxySettings;
22e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.LinkAddress;
23e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.NetworkUtils;
24e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.ProxyInfo;
25e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.RouteInfo;
26e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.StaticIpConfiguration;
27e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.wifi.WifiConfiguration;
28e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.util.Log;
29e33a4bb414892435c016486585c26022cafdab68Roshan Pius
302b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport com.android.internal.util.XmlUtils;
312b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
322b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParser;
332b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParserException;
342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlSerializer;
352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport java.io.IOException;
37e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.Inet4Address;
38e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.InetAddress;
39e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.util.BitSet;
402b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
412b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/**
422b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
432b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * The utility provides methods to write/parse section headers and write/parse values.
442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * This utility is designed for formatting the XML into the following format:
452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * <Document Header>
462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  <Section 1 Header>
472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 1>
482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 2>
492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   ...
502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Sub Section 1 Header>
512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 1>
522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 2>
532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    ...
542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   </Sub Section 1 Header>
552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  </Section 1 Header>
562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * </Document Header>
572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspublic class XmlUtil {
592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    private static final String TAG = "WifiXmlUtil";
602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
62e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at a start tag or the end of document.
63e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
64052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
66e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoStartTag(XmlPullParser in)
672b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
68e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
69e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
70e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
71e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
72e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
73e33a4bb414892435c016486585c26022cafdab68Roshan Pius
74e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
75e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at an end tag or the end of document.
76e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
77052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
78e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
79e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoEndTag(XmlPullParser in)
80e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
81e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
82e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
83e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
84e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
852b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
862b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
882b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Start processing the XML stream at the document header.
892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
92052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
942b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void gotoDocumentStart(XmlPullParser in, String headerName)
952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.beginDocument(in, headerName);
972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
982b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
100e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Move the XML stream to the next section header. The provided outerDepth is used to find
101e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * sub sections within that depth.
1022b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1032b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
1042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
1052b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param outerDepth Find section within this depth.
1062b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return {@code true} if a start tag with the provided name is found, {@code false} otherwise
107052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
1082b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1092b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static boolean gotoNextSection(XmlPullParser in, String headerName, int outerDepth)
1102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
1112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        while (XmlUtils.nextElementWithin(in, outerDepth)) {
1122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            if (in.getName().equals(headerName)) {
1132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius                return true;
1142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            }
1152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        return false;
1172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1192b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
120e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
121e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * and checks if it finds an end tag at the specified depth.
122e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
123e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
124e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
125e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
126052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
127e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
128e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
129e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
130052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius        return (in.nextTag() == XmlPullParser.END_TAG && in.getDepth() == sectionDepth);
131e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
132e33a4bb414892435c016486585c26022cafdab68Roshan Pius
133e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
134e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
135e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * value name in the string provided. This method reads the value contained in current start
136e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * tag.
137e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
138e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * an exception to indicate errors.
139e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
140e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in        XmlPullParser instance pointing to the XML stream.
141e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param valueName An array of one string, used to return the name attribute
142e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *                  of the value's tag.
143e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return value retrieved from the XML stream.
144052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
145e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
146e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
147e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
148e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = XmlUtils.readValueXml(in, valueName);
149e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
150e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // it to the end tag before returning from here.
151e33a4bb414892435c016486585c26022cafdab68Roshan Pius        gotoEndTag(in);
152e33a4bb414892435c016486585c26022cafdab68Roshan Pius        return value;
153e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
154e33a4bb414892435c016486585c26022cafdab68Roshan Pius
155e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
1562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
157e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * provided name. This method moves the stream to the next start tag and reads the value
158e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * contained in it.
1592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
1602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * an exception to indicate errors.
1612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in XmlPullParser instance pointing to the XML stream.
1632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return value retrieved from the XML stream.
164052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if the value read does not match |expectedName|,
165052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     *                                or if parsing errors occur.
1662b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
167e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
1682b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
169e33a4bb414892435c016486585c26022cafdab68Roshan Pius        String[] valueName = new String[1];
170e33a4bb414892435c016486585c26022cafdab68Roshan Pius        XmlUtils.nextElement(in);
171e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = readCurrentValue(in, valueName);
172e33a4bb414892435c016486585c26022cafdab68Roshan Pius        if (valueName[0].equals(expectedName)) {
1732b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            return value;
1742b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1752b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        throw new XmlPullParserException(
176e33a4bb414892435c016486585c26022cafdab68Roshan Pius                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
1772b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1782b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1792b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
1802b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document start with the provided document header name.
1812b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1822b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
1832b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
1842b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1852b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentStart(XmlSerializer out, String headerName)
186e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
1872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startDocument(null, true);
1882b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
1892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
1922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document end with the provided document header name.
1932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1942b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
1952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
1962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentEnd(XmlSerializer out, String headerName)
198e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
1992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2002b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endDocument();
2012b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2022b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2032b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section start header tag with the provided section name.
2052b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2062b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2072b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2082b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2092b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionStart(XmlSerializer out, String headerName)
210e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section end header tag with the provided section name.
2162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2192b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2202b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
221e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2222b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2232b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2242b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2252b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2262b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the value with the provided name in the XML stream using core XmlUtils.
2272b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2282b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out   XmlSerializer instance pointing to the XML stream.
2292b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param name  name of the value.
2302b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param value value to be written.
2312b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2322b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextValue(XmlSerializer out, String name, Object value)
2332b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
2342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.writeValueXml(value, name, out);
2352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
236e33a4bb414892435c016486585c26022cafdab68Roshan Pius
237e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
238e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Utility class to serialize and deseriaize WifConfiguration object to XML & vice versa.
239e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * This is used by both #com.android.server.wifi.WifiConfigStore &
240e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * #com.android.server.wifi.WifiBackupRestore modules.
241e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
242e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
243e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The parse method is written so that any element added/deleted in future revisions can
244e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * be easily handled.
245e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
246e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class WifiConfigurationXmlUtil {
247e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
248e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to WifiConfiguration object elements.
249e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
250e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SSID = "SSID";
251e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_BSSID = "BSSID";
252e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
253e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
254e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
255e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
256e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
257e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
258e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
259e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
260e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SHARED = "Shared";
261e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
262e33a4bb414892435c016486585c26022cafdab68Roshan Pius
263e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
264e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write WepKeys to the XML stream.
265e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
26606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
26706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * XmlUtils serialization doesn't handle this array of nulls well .
26806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * So, write empty strings if some of the keys are not initialized and null if all of
26906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * the elements are empty.
270e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
271e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
272e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
27306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            String[] wepKeysToWrite = new String[wepKeys.length];
27406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            boolean hasWepKey = false;
27506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
27606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeys[i] == null) {
27706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = new String();
27806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
27906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = wepKeys[i];
28006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    hasWepKey = true;
28106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                }
28206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
28306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (hasWepKey) {
28406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
285e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
286e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
287e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
288e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
289e33a4bb414892435c016486585c26022cafdab68Roshan Pius
290e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
291e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements that are common for backup & config store to the
292e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
293e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
294e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
295e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
296e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
297e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeCommonWifiConfigurationElementsToXml(XmlSerializer out,
298e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
299e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
300e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
301e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
302e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
303e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
304e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeWepKeysToXml(out, configuration.wepKeys);
305e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
306e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
307e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
308e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_KEY_MGMT,
309e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedKeyManagement.toByteArray());
310e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
311e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_PROTOCOLS,
312e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedProtocols.toByteArray());
313e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
314e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
315e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedAuthAlgorithms.toByteArray());
316e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
317e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
318e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
319e33a4bb414892435c016486585c26022cafdab68Roshan Pius
320e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
321e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for backup from the provided Configuration to the
322e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
323e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is a subset of the elements serialized for config store.
324e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
325e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
326e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
327e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
328e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeWifiConfigurationToXmlForBackup(XmlSerializer out,
329e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
330e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
331e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeCommonWifiConfigurationElementsToXml(out, configuration);
332e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
333e33a4bb414892435c016486585c26022cafdab68Roshan Pius
334e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
335e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for config store from the provided Configuration
336e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * to the XML stream.
337e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
338e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeWifiConfigurationToXmlForConfigStore(XmlSerializer out,
339e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
340e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
341e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeCommonWifiConfigurationElementsToXml(out, configuration);
342e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // TODO: Will need to add more elements which needs to be persisted.
343e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
344e33a4bb414892435c016486585c26022cafdab68Roshan Pius
345e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
34606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * Populate wepKeys array elements only if they were non-empty in the backup data.
34706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * @throws XmlPullParserException if parsing errors occur.
348e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
349e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
350e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
351e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] wepKeysInData = (String[]) value;
35206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData == null) {
35306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                return;
35406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
35506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData.length != wepKeys.length) {
35606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                throw new XmlPullParserException(
35706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                        "Invalid Wep Keys length: " + wepKeysInData.length);
35806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
35906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
36006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeysInData[i].isEmpty()) {
36106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeys[i] = null;
36206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
363e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    wepKeys[i] = wepKeysInData[i];
364e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
365e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
366e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
367e33a4bb414892435c016486585c26022cafdab68Roshan Pius
368e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
369e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parses the configuration data elements from the provided XML stream to a Configuration.
370e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is used for parsing both backup data and config store data. Looping through
371e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * the tags make it easy to add or remove elements in the future versions if needed.
372e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
373e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
374e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
375e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @return WifiConfiguration object if parsing is successful, null otherwise.
376e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
377e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in,
378e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int outerTagDepth)
379e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
380e33a4bb414892435c016486585c26022cafdab68Roshan Pius            WifiConfiguration configuration = new WifiConfiguration();
381e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String configKeyInData = null;
382e33a4bb414892435c016486585c26022cafdab68Roshan Pius
383e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
384e33a4bb414892435c016486585c26022cafdab68Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
385e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] valueName = new String[1];
386e33a4bb414892435c016486585c26022cafdab68Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
387e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (valueName[0] == null) {
388e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.e(TAG, "Missing value name");
389e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
390e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
391e33a4bb414892435c016486585c26022cafdab68Roshan Pius                switch (valueName[0]) {
392e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CONFIG_KEY:
393e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configKeyInData = (String) value;
394e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
395e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SSID:
396e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.SSID = (String) value;
397e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
398e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_BSSID:
399e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.BSSID = (String) value;
400e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
401e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_PRE_SHARED_KEY:
402e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.preSharedKey = (String) value;
403e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
404e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_KEYS:
405e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
406e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
407e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_TX_KEY_INDEX:
408e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.wepTxKeyIndex = (int) value;
409e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
410e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_HIDDEN_SSID:
411e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.hiddenSSID = (boolean) value;
412e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
413e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_KEY_MGMT:
414e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedKeyMgmt = (byte[]) value;
415e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
416e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
417e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_PROTOCOLS:
418e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedProtocols = (byte[]) value;
419e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
420e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
421e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_AUTH_ALGOS:
422e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedAuthAlgorithms = (byte[]) value;
423e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
424e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
425e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SHARED:
426e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.shared = (boolean) value;
427e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
428e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CREATOR_UID:
429e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.creatorUid = (int) value;
430e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
431e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    default:
432e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        Log.e(TAG, "Unknown value name found: " + valueName[0]);
433e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        return null;
434e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
435e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
436e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // We should now have all the data to calculate the configKey. Compare it against the
437e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // configKey stored in the XML data.
438e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String configKeyCalculated = configuration.configKey();
439e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (configKeyInData == null || !configKeyInData.equals(configKeyCalculated)) {
440e33a4bb414892435c016486585c26022cafdab68Roshan Pius                Log.e(TAG, "Configuration key does not match. Retrieved: " + configKeyInData
441e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        + ", Calculated: " + configKeyCalculated);
442e33a4bb414892435c016486585c26022cafdab68Roshan Pius                return null;
443e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
444e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return configuration;
445e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
446e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
447e33a4bb414892435c016486585c26022cafdab68Roshan Pius
448e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
449e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Utility class to serialize and deseriaize IpConfiguration object to XML & vice versa.
450e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * This is used by both #com.android.server.wifi.WifiConfigStore &
451e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * #com.android.server.wifi.WifiBackupRestore modules.
452e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
453e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class IpConfigurationXmlUtil {
454e33a4bb414892435c016486585c26022cafdab68Roshan Pius
455e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
456e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to IpConfiguration object elements.
457e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
458e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
459e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
460e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
461e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
462e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
463e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
464e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
465e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
466e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
467e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
468e33a4bb414892435c016486585c26022cafdab68Roshan Pius
469e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
470e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the static IP configuration data elements to XML stream.
471e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
472e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeStaticIpConfigurationToXml(XmlSerializer out,
473e33a4bb414892435c016486585c26022cafdab68Roshan Pius                StaticIpConfiguration staticIpConfiguration)
474e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
475e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.ipAddress != null) {
476e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
477e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS,
478e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
479e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
480e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH,
481e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getPrefixLength());
482e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
483e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
484e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS, null);
485e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
486e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
487e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
488e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.gateway != null) {
489e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
490e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS,
491e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.gateway.getHostAddress());
492e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
493e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
494e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS, null);
495e33a4bb414892435c016486585c26022cafdab68Roshan Pius
496e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
497e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.dnsServers != null) {
498e33a4bb414892435c016486585c26022cafdab68Roshan Pius                // Create a string array of DNS server addresses
499e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
500e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int dnsServerIdx = 0;
501e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
502e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
503e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
504e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
505e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
506e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
507e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
508e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
509e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
510e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
511e33a4bb414892435c016486585c26022cafdab68Roshan Pius
512e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
513e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the IP configuration data elements from the provided Configuration to the XML
514e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * stream.
515e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
516e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeIpConfigurationToXml(XmlSerializer out,
517e33a4bb414892435c016486585c26022cafdab68Roshan Pius                IpConfiguration ipConfiguration)
518e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
519e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write IP assignment settings
520e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
521e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.ipAssignment.toString());
522e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.ipAssignment) {
523e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
524e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    writeStaticIpConfigurationToXml(
525e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, ipConfiguration.getStaticIpConfiguration());
526e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
527e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
528e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
529e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
530e33a4bb414892435c016486585c26022cafdab68Roshan Pius
531e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write proxy settings
532e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
533e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_PROXY_SETTINGS,
534e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.proxySettings.toString());
535e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.proxySettings) {
536e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
537e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
538e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_HOST,
539e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getHost());
540e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
541e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PORT,
542e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPort());
543e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
544e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_EXCLUSION_LIST,
545e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getExclusionListAsString());
546e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
547e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
548e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
549e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PAC_FILE,
550e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPacFileUrl().toString());
551e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
552e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
553e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
554e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
555e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
556e33a4bb414892435c016486585c26022cafdab68Roshan Pius
557e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
558e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parse out the static IP configuration from the XML stream.
559e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
560e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
561e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
562e33a4bb414892435c016486585c26022cafdab68Roshan Pius            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
563e33a4bb414892435c016486585c26022cafdab68Roshan Pius
564e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String linkAddressString =
565e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
566e33a4bb414892435c016486585c26022cafdab68Roshan Pius            Integer linkPrefixLength =
567e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
568e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (linkAddressString != null && linkPrefixLength != null) {
569e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress linkAddress = new LinkAddress(
570e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(linkAddressString),
571e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        linkPrefixLength);
572e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (linkAddress.getAddress() instanceof Inet4Address) {
573e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.ipAddress = linkAddress;
574e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
575e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
576e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
577e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
578e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String gatewayAddressString =
579e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
580e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (gatewayAddressString != null) {
581e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress dest = null;
582e33a4bb414892435c016486585c26022cafdab68Roshan Pius                InetAddress gateway =
583e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(gatewayAddressString);
584e33a4bb414892435c016486585c26022cafdab68Roshan Pius                RouteInfo route = new RouteInfo(dest, gateway);
585e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (route.isIPv4Default()) {
586e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.gateway = gateway;
587e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
588e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 default route: " + route);
589e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
590e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
591e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] dnsServerAddressesString =
592e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
593e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (dnsServerAddressesString != null) {
594e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (String dnsServerAddressString : dnsServerAddressesString) {
595e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    InetAddress dnsServerAddress =
596e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
597e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
598e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
599e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
600e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return staticIpConfiguration;
601e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
602e33a4bb414892435c016486585c26022cafdab68Roshan Pius
603e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
604e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parses the IP configuration data elements from the provided XML stream to a
605e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * IpConfiguration.
606e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
607e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
608e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
609e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @return IpConfiguration object if parsing is successful, null otherwise.
610e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
611e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in,
612e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int outerTagDepth)
613e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
614e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpConfiguration ipConfiguration = new IpConfiguration();
615e33a4bb414892435c016486585c26022cafdab68Roshan Pius
616e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the IP assignment info first.
617e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String ipAssignmentString =
618e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
619e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
620e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setIpAssignment(ipAssignment);
621e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipAssignment) {
622e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
623e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
624e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
625e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case DHCP:
626e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
627e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
628e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
629e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.wtf(TAG, "Unknown ip assignment type: " + ipAssignment);
630e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
631e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
632e33a4bb414892435c016486585c26022cafdab68Roshan Pius
633e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the proxy settings next.
634e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String proxySettingsString =
635e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
636e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
637e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setProxySettings(proxySettings);
638e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (proxySettings) {
639e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
640e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyHost =
641e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
642e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    int proxyPort =
643e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
644e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyExclusionList =
645e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(
646e33a4bb414892435c016486585c26022cafdab68Roshan Pius                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
647e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(
648e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
649e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
650e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
651e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyPacFile =
652e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
653e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
654e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
655e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case NONE:
656e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
657e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
658e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
659e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.wtf(TAG, "Unknown proxy settings type: " + proxySettings);
660e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
661e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
662e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return ipConfiguration;
663e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
664e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
6652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius}
6662b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
667