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;
23ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kimimport android.net.MacAddress;
24e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.NetworkUtils;
25e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.ProxyInfo;
26e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.RouteInfo;
27e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.StaticIpConfiguration;
28e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.wifi.WifiConfiguration;
295d3609b1931180c37d7292619146ad7d33df9a21Roshan Piusimport android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
30642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Piusimport android.net.wifi.WifiEnterpriseConfig;
31e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.util.Log;
322fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Piusimport android.util.Pair;
33e33a4bb414892435c016486585c26022cafdab68Roshan Pius
342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport com.android.internal.util.XmlUtils;
352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParser;
372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParserException;
382b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlSerializer;
392b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
402b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport java.io.IOException;
41e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.Inet4Address;
42e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.InetAddress;
430e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Piusimport java.util.Arrays;
44e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.util.BitSet;
45030c5debfefddf0512cd53fec48b269c08d9972eRoshan Piusimport java.util.HashMap;
462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/**
482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * The utility provides methods to write/parse section headers and write/parse values.
502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * This utility is designed for formatting the XML into the following format:
512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * <Document Header>
522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  <Section 1 Header>
532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 1>
542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 2>
552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   ...
562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Sub Section 1 Header>
572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 1>
582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 2>
592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    ...
602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   </Sub Section 1 Header>
612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  </Section 1 Header>
622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * </Document Header>
63d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius *
64d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius * Note: These utility methods are meant to be used for:
65d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius * 1. Backup/restore wifi network data to/from cloud.
66d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius * 2. Persisting wifi network data to/from disk.
672b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
682b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspublic class XmlUtil {
692b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    private static final String TAG = "WifiXmlUtil";
702b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
712b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
72e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at a start tag or the end of document.
73e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
74052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
752b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
76e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoStartTag(XmlPullParser in)
772b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
78e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
79e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
80e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
81e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
82e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
83e33a4bb414892435c016486585c26022cafdab68Roshan Pius
84e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
85e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at an end tag or the end of document.
86e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
87052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
88e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
89e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoEndTag(XmlPullParser in)
90e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
91e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
92e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
93e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
94e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
982b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Start processing the XML stream at the document header.
992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1002b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
1012b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
102052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
1032b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void gotoDocumentStart(XmlPullParser in, String headerName)
1052b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
1062b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.beginDocument(in, headerName);
1072b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1082b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1092b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
110c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header or indicate if there are no more sections.
111c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
112c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
113c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across sections if the ordering of sections are variable. The returned name
114c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * can be used to decide what section is next.
1152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
117c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param headerName An array of one string, used to return the name of the next section.
1182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param outerDepth Find section within this depth.
119c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
120052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
1212b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
122c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static boolean gotoNextSectionOrEnd(
123c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String[] headerName, int outerDepth)
124c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throws XmlPullParserException, IOException {
125c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (XmlUtils.nextElementWithin(in, outerDepth)) {
126c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            headerName[0] = in.getName();
127c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            return true;
128c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        }
129c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        return false;
130c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    }
131c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius
132c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    /**
133c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header or indicate if there are no more sections.
134c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * If a section, exists ensure that the name matches the provided name.
135c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
136c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
137c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across repeated sections until the end.
138c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
139c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
140c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param expectedName expected name for the section header.
141c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param outerDepth   Find section within this depth.
142c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
143c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @throws XmlPullParserException if the section header name does not match |expectedName|,
144c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *                                or if parsing errors occur.
145c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     */
146c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static boolean gotoNextSectionWithNameOrEnd(
147c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String expectedName, int outerDepth)
1482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
149c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        String[] headerName = new String[1];
150c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (gotoNextSectionOrEnd(in, headerName, outerDepth)) {
151c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            if (headerName[0].equals(expectedName)) {
1522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius                return true;
1532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            }
154c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throw new XmlPullParserException(
155c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    "Next section name does not match expected name: " + expectedName);
1562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        return false;
1582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
161c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header and ensure that the name matches the provided
162c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * name.
163c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
164c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
165c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across sections if the ordering of sections are fixed.
166c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
167c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
168c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param expectedName expected name for the section header.
169c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param outerDepth   Find section within this depth.
170c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @throws XmlPullParserException if the section header name does not match |expectedName|,
171c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *                                there are no more sections or if parsing errors occur.
172c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     */
173c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static void gotoNextSectionWithName(
174c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String expectedName, int outerDepth)
175c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throws XmlPullParserException, IOException {
176c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (!gotoNextSectionWithNameOrEnd(in, expectedName, outerDepth)) {
177c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throw new XmlPullParserException("Section not found. Expected: " + expectedName);
178c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        }
179c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    }
180c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius
181c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    /**
182e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
183e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * and checks if it finds an end tag at the specified depth.
184e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
185e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
186e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
187e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
188052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
189e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
190e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
191e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
192c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        return !XmlUtils.nextElementWithin(in, sectionDepth);
193e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
194e33a4bb414892435c016486585c26022cafdab68Roshan Pius
195e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
196e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
197e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * value name in the string provided. This method reads the value contained in current start
198e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * tag.
199e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
200e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * an exception to indicate errors.
201e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
202e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in        XmlPullParser instance pointing to the XML stream.
203e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param valueName An array of one string, used to return the name attribute
204e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *                  of the value's tag.
205e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return value retrieved from the XML stream.
206052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
207e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
208e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
209e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
210e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = XmlUtils.readValueXml(in, valueName);
211e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
212e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // it to the end tag before returning from here.
213e33a4bb414892435c016486585c26022cafdab68Roshan Pius        gotoEndTag(in);
214e33a4bb414892435c016486585c26022cafdab68Roshan Pius        return value;
215e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
216e33a4bb414892435c016486585c26022cafdab68Roshan Pius
217e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
2182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
219e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * provided name. This method moves the stream to the next start tag and reads the value
220e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * contained in it.
2212b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
2222b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * an exception to indicate errors.
2232b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2242b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in XmlPullParser instance pointing to the XML stream.
2252b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return value retrieved from the XML stream.
226052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if the value read does not match |expectedName|,
227052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     *                                or if parsing errors occur.
2282b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
229e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
2302b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
231e33a4bb414892435c016486585c26022cafdab68Roshan Pius        String[] valueName = new String[1];
232e33a4bb414892435c016486585c26022cafdab68Roshan Pius        XmlUtils.nextElement(in);
233e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = readCurrentValue(in, valueName);
234e33a4bb414892435c016486585c26022cafdab68Roshan Pius        if (valueName[0].equals(expectedName)) {
2352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            return value;
2362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
2372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        throw new XmlPullParserException(
238e33a4bb414892435c016486585c26022cafdab68Roshan Pius                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
2392b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2402b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2412b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2422b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document start with the provided document header name.
2432b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentStart(XmlSerializer out, String headerName)
248e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startDocument(null, true);
2502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document end with the provided document header name.
2552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentEnd(XmlSerializer out, String headerName)
260e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endDocument();
2632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2642b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2662b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section start header tag with the provided section name.
2672b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2682b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2692b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2702b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2712b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionStart(XmlSerializer out, String headerName)
272e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2732b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2742b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2752b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2762b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2772b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section end header tag with the provided section name.
2782b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2792b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2802b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2812b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2822b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
283e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2842b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2852b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2862b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2882b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the value with the provided name in the XML stream using core XmlUtils.
2892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out   XmlSerializer instance pointing to the XML stream.
2912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param name  name of the value.
2922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param value value to be written.
2932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2942b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextValue(XmlSerializer out, String name, Object value)
2952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
2962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.writeValueXml(value, name, out);
2972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
298e33a4bb414892435c016486585c26022cafdab68Roshan Pius
299e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
300feff7928414673632bfe89575cf0d53ec8950c32Michal Karpinski     * Utility class to serialize and deserialize {@link WifiConfiguration} object to XML &
3015d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * vice versa.
3025d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
3035d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * {@link com.android.server.wifi.WifiBackupRestore} modules.
304e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
305e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
306e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The parse method is written so that any element added/deleted in future revisions can
307e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * be easily handled.
308e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
309e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class WifiConfigurationXmlUtil {
310e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
311e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to WifiConfiguration object elements.
312e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
313e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SSID = "SSID";
314e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_BSSID = "BSSID";
315e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
316e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
317e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
318e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
319e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
320241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius        public static final String XML_TAG_REQUIRE_PMF = "RequirePMF";
321e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
322e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
323e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
324241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius        public static final String XML_TAG_ALLOWED_GROUP_CIPHERS = "AllowedGroupCiphers";
325241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius        public static final String XML_TAG_ALLOWED_PAIRWISE_CIPHERS = "AllowedPairwiseCiphers";
326e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SHARED = "Shared";
3276296902ef69724b106973b57b268c30ea4f1ab51Roshan Pius        public static final String XML_TAG_STATUS = "Status";
328030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_FQDN = "FQDN";
329030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_PROVIDER_FRIENDLY_NAME = "ProviderFriendlyName";
330030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LINKED_NETWORKS_LIST = "LinkedNetworksList";
331030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_DEFAULT_GW_MAC_ADDRESS = "DefaultGwMacAddress";
332030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
333030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NO_INTERNET_ACCESS_EXPECTED = "NoInternetAccessExpected";
334030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USER_APPROVED = "UserApproved";
335030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_METERED_HINT = "MeteredHint";
3364befdc216d00e2dce59097fb1f8195afe489fd32Jeff Sharkey        public static final String XML_TAG_METERED_OVERRIDE = "MeteredOverride";
337030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores";
338030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation";
339e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
3402fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius        public static final String XML_TAG_CREATOR_NAME = "CreatorName";
341030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_CREATION_TIME = "CreationTime";
342030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid";
343030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName";
344030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid";
3459ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu        public static final String XML_TAG_IS_LEGACY_PASSPOINT_CONFIG = "IsLegacyPasspointConfig";
3469ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu        public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs";
347ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim        public static final String XML_TAG_RANDOMIZED_MAC_ADDRESS = "RandomizedMacAddress";
348e33a4bb414892435c016486585c26022cafdab68Roshan Pius
349e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
350e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write WepKeys to the XML stream.
351e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
35206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
35306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * XmlUtils serialization doesn't handle this array of nulls well .
35406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * So, write empty strings if some of the keys are not initialized and null if all of
35506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * the elements are empty.
356e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
357e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
358e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
35906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            String[] wepKeysToWrite = new String[wepKeys.length];
36006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            boolean hasWepKey = false;
36106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
36206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeys[i] == null) {
36306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = new String();
36406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
36506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = wepKeys[i];
36606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    hasWepKey = true;
36706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                }
36806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
36906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (hasWepKey) {
37006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
371e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
372e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
373e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
374e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
375e33a4bb414892435c016486585c26022cafdab68Roshan Pius
376e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
377e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements that are common for backup & config store to the
378e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
379e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
380e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
381e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
382e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
383c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeCommonElementsToXml(
384c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, WifiConfiguration configuration)
385e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
386e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
387e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
388e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
389e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
390e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeWepKeysToXml(out, configuration.wepKeys);
391e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
392e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
393241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_REQUIRE_PMF, configuration.requirePMF);
394e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
395e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_KEY_MGMT,
396e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedKeyManagement.toByteArray());
397e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
398e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_PROTOCOLS,
399e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedProtocols.toByteArray());
400e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
401e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
402e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedAuthAlgorithms.toByteArray());
403241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius            XmlUtil.writeNextValue(
404241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    out, XML_TAG_ALLOWED_GROUP_CIPHERS,
405241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    configuration.allowedGroupCiphers.toByteArray());
406241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius            XmlUtil.writeNextValue(
407241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    out, XML_TAG_ALLOWED_PAIRWISE_CIPHERS,
408241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    configuration.allowedPairwiseCiphers.toByteArray());
409e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
410e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
411e33a4bb414892435c016486585c26022cafdab68Roshan Pius
412e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
413e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for backup from the provided Configuration to the
414e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
415e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is a subset of the elements serialized for config store.
416e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
417e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
418e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
419e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
420c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)
421e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
422c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            writeCommonElementsToXml(out, configuration);
423e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
424e33a4bb414892435c016486585c26022cafdab68Roshan Pius
425e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
426e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for config store from the provided Configuration
427e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * to the XML stream.
428642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
429642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
430642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
431e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
432c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXmlForConfigStore(
433c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, WifiConfiguration configuration)
434e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
435c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            writeCommonElementsToXml(out, configuration);
4366296902ef69724b106973b57b268c30ea4f1ab51Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_STATUS, configuration.status);
437030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
438030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
439030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName);
440030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
441030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations);
442030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
443030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress);
444030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
445030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess);
446030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
447030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED,
448030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    configuration.noInternetAccessExpected);
449030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved);
450030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint);
4514befdc216d00e2dce59097fb1f8195afe489fd32Jeff Sharkey            XmlUtil.writeNextValue(out, XML_TAG_METERED_OVERRIDE, configuration.meteredOverride);
452030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
453030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores);
454030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation);
4552fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
4562fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName);
457030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime);
458030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid);
459030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName);
460030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid);
4619ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu            XmlUtil.writeNextValue(
4629ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    out, XML_TAG_IS_LEGACY_PASSPOINT_CONFIG,
4639ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    configuration.isLegacyPasspointConfig);
4649ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu            XmlUtil.writeNextValue(
4659ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    out, XML_TAG_ROAMING_CONSORTIUM_OIS, configuration.roamingConsortiumIds);
466ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim            XmlUtil.writeNextValue(out, XML_TAG_RANDOMIZED_MAC_ADDRESS,
467ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim                    configuration.getRandomizedMacAddress().toString());
468e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
469e33a4bb414892435c016486585c26022cafdab68Roshan Pius
470e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
47106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * Populate wepKeys array elements only if they were non-empty in the backup data.
4722fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         *
47306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * @throws XmlPullParserException if parsing errors occur.
474e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
475e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
476e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
477e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] wepKeysInData = (String[]) value;
47806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData == null) {
47906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                return;
48006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
48106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData.length != wepKeys.length) {
48206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                throw new XmlPullParserException(
48306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                        "Invalid Wep Keys length: " + wepKeysInData.length);
48406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
48506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
48606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeysInData[i].isEmpty()) {
48706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeys[i] = null;
48806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
489e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    wepKeys[i] = wepKeysInData[i];
490e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
491e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
492e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
493e33a4bb414892435c016486585c26022cafdab68Roshan Pius
494e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
4955d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the configuration data elements from the provided XML stream to a
4965d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * WifiConfiguration object.
497e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is used for parsing both backup data and config store data. Looping through
498e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * the tags make it easy to add or remove elements in the future versions if needed.
499e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
500e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
501e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
5022fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
5032fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * null otherwise.
504e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
505c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static Pair<String, WifiConfiguration> parseFromXml(
5062fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                XmlPullParser in, int outerTagDepth)
507e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
508e33a4bb414892435c016486585c26022cafdab68Roshan Pius            WifiConfiguration configuration = new WifiConfiguration();
509e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String configKeyInData = null;
510e33a4bb414892435c016486585c26022cafdab68Roshan Pius
511e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
512e33a4bb414892435c016486585c26022cafdab68Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
513e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] valueName = new String[1];
514e33a4bb414892435c016486585c26022cafdab68Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
515e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (valueName[0] == null) {
516c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Missing value name");
517e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
518e33a4bb414892435c016486585c26022cafdab68Roshan Pius                switch (valueName[0]) {
519e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CONFIG_KEY:
520e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configKeyInData = (String) value;
521e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
522e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SSID:
523e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.SSID = (String) value;
524e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
525e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_BSSID:
526e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.BSSID = (String) value;
527e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
528e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_PRE_SHARED_KEY:
529e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.preSharedKey = (String) value;
530e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
531e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_KEYS:
532e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
533e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
534e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_TX_KEY_INDEX:
535e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.wepTxKeyIndex = (int) value;
536e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
537e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_HIDDEN_SSID:
538e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.hiddenSSID = (boolean) value;
539e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
540241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    case XML_TAG_REQUIRE_PMF:
541241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        configuration.requirePMF = (boolean) value;
542241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        break;
543e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_KEY_MGMT:
544e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedKeyMgmt = (byte[]) value;
545e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
546e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
547e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_PROTOCOLS:
548e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedProtocols = (byte[]) value;
549e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
550e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
551e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_AUTH_ALGOS:
552e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedAuthAlgorithms = (byte[]) value;
553e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
554e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
555241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    case XML_TAG_ALLOWED_GROUP_CIPHERS:
556241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        byte[] allowedGroupCiphers = (byte[]) value;
557241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
558241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        break;
559241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                    case XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
560241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        byte[] allowedPairwiseCiphers = (byte[]) value;
561241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        configuration.allowedPairwiseCiphers =
562241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                                BitSet.valueOf(allowedPairwiseCiphers);
563241605aebc6a8f55624026e8b72246bceb1c2ac2Roshan Pius                        break;
564e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SHARED:
565e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.shared = (boolean) value;
566e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
5676296902ef69724b106973b57b268c30ea4f1ab51Roshan Pius                    case XML_TAG_STATUS:
568d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        int status = (int) value;
569d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        // Any network which was CURRENT before reboot needs
570d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        // to be restored to ENABLED.
571d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        if (status == WifiConfiguration.Status.CURRENT) {
572d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                            status = WifiConfiguration.Status.ENABLED;
573d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        }
574d44fca25d34d80d98c242423c3a5504a325553abRoshan Pius                        configuration.status = status;
5756296902ef69724b106973b57b268c30ea4f1ab51Roshan Pius                        break;
576030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_FQDN:
577030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.FQDN = (String) value;
578030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
579030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
580030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.providerFriendlyName = (String) value;
581030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
582030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LINKED_NETWORKS_LIST:
583030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
584030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
585030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
586030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.defaultGwMacAddress = (String) value;
587030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
588030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
589030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.validatedInternetAccess = (boolean) value;
590030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
591030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
592030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.noInternetAccessExpected = (boolean) value;
593030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
594030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USER_APPROVED:
595030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.userApproved = (int) value;
596030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
597030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_METERED_HINT:
598030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.meteredHint = (boolean) value;
599030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
6004befdc216d00e2dce59097fb1f8195afe489fd32Jeff Sharkey                    case XML_TAG_METERED_OVERRIDE:
6014befdc216d00e2dce59097fb1f8195afe489fd32Jeff Sharkey                        configuration.meteredOverride = (int) value;
6024befdc216d00e2dce59097fb1f8195afe489fd32Jeff Sharkey                        break;
603030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USE_EXTERNAL_SCORES:
604030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.useExternalScores = (boolean) value;
605030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
606030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NUM_ASSOCIATION:
607030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.numAssociation = (int) value;
608030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
609e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CREATOR_UID:
610e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.creatorUid = (int) value;
611e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
6122fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                    case XML_TAG_CREATOR_NAME:
6132fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        configuration.creatorName = (String) value;
6142fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        break;
615030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_CREATION_TIME:
616030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.creationTime = (String) value;
617030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
618030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_UID:
619030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateUid = (int) value;
620030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
621030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_NAME:
622030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateName = (String) value;
623030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
624030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_CONNECT_UID:
625030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastConnectUid = (int) value;
626030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
6279ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG:
6289ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        configuration.isLegacyPasspointConfig = (boolean) value;
6299ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        break;
6309ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    case XML_TAG_ROAMING_CONSORTIUM_OIS:
6319ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        configuration.roamingConsortiumIds = (long[]) value;
6329ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        break;
633ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim                    case XML_TAG_RANDOMIZED_MAC_ADDRESS:
634ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim                        configuration.setRandomizedMacAddress(
635ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim                                MacAddress.fromString((String) value));
636ab0597767ce87aae78b4ce1cb6c5d0d46050eed4Jong Wook Kim                        break;
637e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    default:
638c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                        throw new XmlPullParserException(
639c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                                "Unknown value name found: " + valueName[0]);
640e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
641e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
6422fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            return Pair.create(configKeyInData, configuration);
643e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
644e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
645e33a4bb414892435c016486585c26022cafdab68Roshan Pius
646e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
6475d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * Utility class to serialize and deseriaize {@link IpConfiguration} object to XML & vice versa.
6485d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
6495d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * {@link com.android.server.wifi.WifiBackupRestore} modules.
650e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
651e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class IpConfigurationXmlUtil {
652e33a4bb414892435c016486585c26022cafdab68Roshan Pius
653e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
654e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to IpConfiguration object elements.
655e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
656e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
657e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
658e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
659e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
660e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
661e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
662e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
663e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
664e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
665e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
666e33a4bb414892435c016486585c26022cafdab68Roshan Pius
667e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
668e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the static IP configuration data elements to XML stream.
669e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
670c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        private static void writeStaticIpConfigurationToXml(
671c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, StaticIpConfiguration staticIpConfiguration)
672e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
673e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.ipAddress != null) {
674e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
675e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS,
676e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
677e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
678e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH,
679e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getPrefixLength());
680e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
681e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
682e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS, null);
683e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
684e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
685e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
686e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.gateway != null) {
687e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
688e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS,
689e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.gateway.getHostAddress());
690e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
691e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
692e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS, null);
693e33a4bb414892435c016486585c26022cafdab68Roshan Pius
694e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
695e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.dnsServers != null) {
696e33a4bb414892435c016486585c26022cafdab68Roshan Pius                // Create a string array of DNS server addresses
697e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
698e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int dnsServerIdx = 0;
699e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
700e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
701e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
702e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
703e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
704e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
705e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
706e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
707e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
708e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
709e33a4bb414892435c016486585c26022cafdab68Roshan Pius
710e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
711e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the IP configuration data elements from the provided Configuration to the XML
712e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * stream.
713642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
714642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out             XmlSerializer instance pointing to the XML stream.
715642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param ipConfiguration IpConfiguration object to be serialized.
716e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
717c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXml(XmlSerializer out, IpConfiguration ipConfiguration)
718e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
719e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write IP assignment settings
720e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
721e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.ipAssignment.toString());
722e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.ipAssignment) {
723e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
724e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    writeStaticIpConfigurationToXml(
725e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, ipConfiguration.getStaticIpConfiguration());
726e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
727e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
728e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
729e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
730e33a4bb414892435c016486585c26022cafdab68Roshan Pius
731e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write proxy settings
732e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
733e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_PROXY_SETTINGS,
734e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.proxySettings.toString());
735e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.proxySettings) {
736e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
737e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
738e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_HOST,
739e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getHost());
740e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
741e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PORT,
742e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPort());
743e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
744e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_EXCLUSION_LIST,
745e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getExclusionListAsString());
746e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
747e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
748e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
749e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PAC_FILE,
750e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPacFileUrl().toString());
751e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
752e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
753e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
754e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
755e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
756e33a4bb414892435c016486585c26022cafdab68Roshan Pius
757e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
758e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parse out the static IP configuration from the XML stream.
759e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
760e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
761e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
762e33a4bb414892435c016486585c26022cafdab68Roshan Pius            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
763e33a4bb414892435c016486585c26022cafdab68Roshan Pius
764e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String linkAddressString =
765e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
766e33a4bb414892435c016486585c26022cafdab68Roshan Pius            Integer linkPrefixLength =
767e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
768e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (linkAddressString != null && linkPrefixLength != null) {
769e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress linkAddress = new LinkAddress(
770e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(linkAddressString),
771e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        linkPrefixLength);
772e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (linkAddress.getAddress() instanceof Inet4Address) {
773e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.ipAddress = linkAddress;
774e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
775e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
776e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
777e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
778e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String gatewayAddressString =
779e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
780e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (gatewayAddressString != null) {
781e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress dest = null;
782e33a4bb414892435c016486585c26022cafdab68Roshan Pius                InetAddress gateway =
783e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(gatewayAddressString);
784e33a4bb414892435c016486585c26022cafdab68Roshan Pius                RouteInfo route = new RouteInfo(dest, gateway);
785e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (route.isIPv4Default()) {
786e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.gateway = gateway;
787e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
788e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 default route: " + route);
789e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
790e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
791e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] dnsServerAddressesString =
792e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
793e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (dnsServerAddressesString != null) {
794e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (String dnsServerAddressString : dnsServerAddressesString) {
795e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    InetAddress dnsServerAddress =
796e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
797e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
798e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
799e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
800e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return staticIpConfiguration;
801e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
802e33a4bb414892435c016486585c26022cafdab68Roshan Pius
803e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
8045d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the IP configuration data elements from the provided XML stream to an
8055d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * IpConfiguration object.
806e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
807e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
808e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
809e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @return IpConfiguration object if parsing is successful, null otherwise.
810e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
811c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static IpConfiguration parseFromXml(XmlPullParser in, int outerTagDepth)
812e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
813e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpConfiguration ipConfiguration = new IpConfiguration();
814e33a4bb414892435c016486585c26022cafdab68Roshan Pius
815e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the IP assignment info first.
816e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String ipAssignmentString =
817e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
818e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
819e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setIpAssignment(ipAssignment);
820e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipAssignment) {
821e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
822e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
823e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
824e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case DHCP:
825e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
826e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
827e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
828c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment);
829e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
830e33a4bb414892435c016486585c26022cafdab68Roshan Pius
831e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the proxy settings next.
832e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String proxySettingsString =
833e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
834e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
835e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setProxySettings(proxySettings);
836e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (proxySettings) {
837e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
838e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyHost =
839e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
840e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    int proxyPort =
841e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
842e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyExclusionList =
843e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(
844e33a4bb414892435c016486585c26022cafdab68Roshan Pius                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
845e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(
846e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
847e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
848e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
849e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyPacFile =
850e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
851e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
852e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
853e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case NONE:
854e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
855e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
856e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
857c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException(
858c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                            "Unknown proxy settings type: " + proxySettings);
859e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
860e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return ipConfiguration;
861e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
862e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
8635d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8645d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    /**
8655d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * Utility class to serialize and deseriaize {@link NetworkSelectionStatus} object to XML &
8665d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
8675d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     */
8685d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    public static class NetworkSelectionStatusXmlUtil {
8695d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8705d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
8715d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * List of XML tags corresponding to NetworkSelectionStatus object elements.
8725d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
8735d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_SELECTION_STATUS = "SelectionStatus";
8745d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_DISABLE_REASON = "DisableReason";
8755d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_CONNECT_CHOICE = "ConnectChoice";
8765d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_CONNECT_CHOICE_TIMESTAMP = "ConnectChoiceTimeStamp";
8775d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
8785d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8795d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
8805d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Write the NetworkSelectionStatus data elements from the provided status to the XML
8815d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * stream.
882642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
8830e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius         * @param out             XmlSerializer instance pointing to the XML stream.
8840e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius         * @param selectionStatus NetworkSelectionStatus object to be serialized.
8855d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
8860e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius        public static void writeToXml(XmlSerializer out, NetworkSelectionStatus selectionStatus)
8875d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                throws XmlPullParserException, IOException {
8885d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            XmlUtil.writeNextValue(
8890e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_SELECTION_STATUS, selectionStatus.getNetworkStatusString());
8900e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(
8910e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_DISABLE_REASON, selectionStatus.getNetworkDisableReasonString());
8920e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONNECT_CHOICE, selectionStatus.getConnectChoice());
8935d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            XmlUtil.writeNextValue(
8940e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_CONNECT_CHOICE_TIMESTAMP,
8950e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    selectionStatus.getConnectChoiceTimestamp());
8960e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(
8970e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_HAS_EVER_CONNECTED, selectionStatus.getHasEverConnected());
8985d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        }
8995d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
9005d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
9015d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the NetworkSelectionStatus data elements from the provided XML stream to a
9025d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * NetworkSelectionStatus object.
9035d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         *
9045d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
9055d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
9065d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @return NetworkSelectionStatus object if parsing is successful, null otherwise.
9075d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
908c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static NetworkSelectionStatus parseFromXml(XmlPullParser in, int outerTagDepth)
9095d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                throws XmlPullParserException, IOException {
9100e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            NetworkSelectionStatus selectionStatus = new NetworkSelectionStatus();
9110e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            String statusString = "";
9120e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            String disableReasonString = "";
9135d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
9145d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
9155d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
9165d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                String[] valueName = new String[1];
9175d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
9185d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                if (valueName[0] == null) {
919c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Missing value name");
9205d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                }
9215d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                switch (valueName[0]) {
9225d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_SELECTION_STATUS:
9230e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        statusString = (String) value;
9245d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
9255d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_DISABLE_REASON:
9260e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        disableReasonString = (String) value;
9275d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
9285d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_CONNECT_CHOICE:
9290e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setConnectChoice((String) value);
9305d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
9315d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_CONNECT_CHOICE_TIMESTAMP:
9320e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setConnectChoiceTimestamp((long) value);
9335d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
9345d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_HAS_EVER_CONNECTED:
9350e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setHasEverConnected((boolean) value);
9365d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
9375d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    default:
938c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                        throw new XmlPullParserException(
939c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                                "Unknown value name found: " + valueName[0]);
9405d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                }
9415d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            }
9420e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // Now figure out the network selection status codes from |selectionStatusString| &
9430e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // |disableReasonString|.
9440e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            int status =
9450e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_STATUS)
9460e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                            .indexOf(statusString);
9470e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            int disableReason =
9480e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_DISABLE_REASON)
9490e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                            .indexOf(disableReasonString);
9500e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius
9510e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // If either of the above codes are invalid or if the network was temporarily disabled
9520e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // (blacklisted), restore the status as enabled. We don't want to persist blacklists
9530e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // across reboots.
9540e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            if (status == -1 || disableReason == -1 ||
9550e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    status == NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
9560e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                status = NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
9570e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                disableReason = NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
9580e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            }
9590e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            selectionStatus.setNetworkSelectionStatus(status);
9600e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            selectionStatus.setNetworkSelectionDisableReason(disableReason);
9610e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            return selectionStatus;
9625d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        }
9635d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    }
964642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
965642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    /**
966642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     * Utility class to serialize and deseriaize {@link WifiEnterpriseConfig} object to XML &
967642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
968642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     */
969642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    public static class WifiEnterpriseConfigXmlUtil {
970642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
971642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
972642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * List of XML tags corresponding to WifiEnterpriseConfig object elements.
973642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
974642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_IDENTITY = "Identity";
975642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ANON_IDENTITY = "AnonIdentity";
976642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PASSWORD = "Password";
977642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CLIENT_CERT = "ClientCert";
978642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CA_CERT = "CaCert";
979642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_SUBJECT_MATCH = "SubjectMatch";
980642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ENGINE = "Engine";
981642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ENGINE_ID = "EngineId";
982642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PRIVATE_KEY_ID = "PrivateKeyId";
983642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ALT_SUBJECT_MATCH = "AltSubjectMatch";
984642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_DOM_SUFFIX_MATCH = "DomSuffixMatch";
985642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CA_PATH = "CaPath";
986642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_EAP_METHOD = "EapMethod";
987642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PHASE2_METHOD = "Phase2Method";
9889ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu        public static final String XML_TAG_PLMN = "PLMN";
9899ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu        public static final String XML_TAG_REALM = "Realm";
990642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
991642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
992642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * Write the WifiEnterpriseConfig data elements from the provided config to the XML
993642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * stream.
994642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
995642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out              XmlSerializer instance pointing to the XML stream.
996642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param enterpriseConfig WifiEnterpriseConfig object to be serialized.
997642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
998642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)
999642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                throws XmlPullParserException, IOException {
1000642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IDENTITY,
1001d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY));
1002642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY,
1003d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY));
1004642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PASSWORD,
1005d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY));
1006642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT,
1007d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY));
1008642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CA_CERT,
1009d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY));
1010642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SUBJECT_MATCH,
1011d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY));
1012642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ENGINE,
1013d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY));
1014642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ENGINE_ID,
1015d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY));
1016642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRIVATE_KEY_ID,
1017d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY));
1018642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ALT_SUBJECT_MATCH,
1019d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY));
1020642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_DOM_SUFFIX_MATCH,
1021d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY));
1022642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CA_PATH,
1023d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY));
1024642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod());
1025642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method());
10269ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu            XmlUtil.writeNextValue(out, XML_TAG_PLMN, enterpriseConfig.getPlmn());
10279ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu            XmlUtil.writeNextValue(out, XML_TAG_REALM, enterpriseConfig.getRealm());
1028642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        }
1029642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
1030642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
1031642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object.
1032642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
1033642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
1034642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
1035642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @return WifiEnterpriseConfig object if parsing is successful, null otherwise.
1036642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
1037642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth)
1038642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                throws XmlPullParserException, IOException {
1039642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
1040642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
1041642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
1042642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
1043642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                String[] valueName = new String[1];
1044642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
1045642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                if (valueName[0] == null) {
1046642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    throw new XmlPullParserException("Missing value name");
1047642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                }
1048642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                switch (valueName[0]) {
1049642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_IDENTITY:
1050642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1051642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
1052642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1053642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ANON_IDENTITY:
1054642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1055642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
1056642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1057642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PASSWORD:
1058642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1059642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
1060642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1061642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CLIENT_CERT:
1062642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1063642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
1064642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1065642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CA_CERT:
1066642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1067642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
1068642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1069642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_SUBJECT_MATCH:
1070642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1071642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
1072642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1073642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ENGINE:
1074642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1075642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ENGINE_KEY, (String) value);
1076642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1077642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ENGINE_ID:
1078642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1079642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
1080642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1081642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PRIVATE_KEY_ID:
1082642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1083642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
1084642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1085642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ALT_SUBJECT_MATCH:
1086642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1087642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
1088642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1089642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_DOM_SUFFIX_MATCH:
1090642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1091642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
1092642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1093642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CA_PATH:
1094642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1095642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
1096642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1097642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_EAP_METHOD:
1098642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setEapMethod((int) value);
1099642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1100642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PHASE2_METHOD:
1101642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setPhase2Method((int) value);
1102642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
11039ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    case XML_TAG_PLMN:
11049ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        enterpriseConfig.setPlmn((String) value);
11059ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        break;
11069ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                    case XML_TAG_REALM:
11079ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        enterpriseConfig.setRealm((String) value);
11089ef555a48ac600c8766f703fa60db15b69e20301Peter Qiu                        break;
1109642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    default:
1110642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        throw new XmlPullParserException(
1111642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                "Unknown value name found: " + valueName[0]);
1112642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                }
1113642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            }
1114642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            return enterpriseConfig;
1115642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        }
1116642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    }
11172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius}
11182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1119