XmlUtil.java revision d83ef7d8c4948afc328d8ef0e746b32c195f271e
12b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/*
22b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Copyright (C) 2016 The Android Open Source Project
32b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
42b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Licensed under the Apache License, Version 2.0 (the "License");
52b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * you may not use this file except in compliance with the License.
62b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * You may obtain a copy of the License at
72b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
82b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *      http://www.apache.org/licenses/LICENSE-2.0
92b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Unless required by applicable law or agreed to in writing, software
112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * distributed under the License is distributed on an "AS IS" BASIS,
122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * See the License for the specific language governing permissions and
142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * limitations under the License.
152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspackage com.android.server.wifi.util;
182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
19e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration;
20e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.IpAssignment;
21e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.ProxySettings;
22e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.LinkAddress;
23e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.NetworkUtils;
24e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.ProxyInfo;
25e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.RouteInfo;
26e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.StaticIpConfiguration;
27e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.wifi.WifiConfiguration;
285d3609b1931180c37d7292619146ad7d33df9a21Roshan Piusimport android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
29642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Piusimport android.net.wifi.WifiEnterpriseConfig;
30e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.util.Log;
312fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Piusimport android.util.Pair;
32e33a4bb414892435c016486585c26022cafdab68Roshan Pius
332b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport com.android.internal.util.XmlUtils;
342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParser;
362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParserException;
372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlSerializer;
382b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
392b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport java.io.IOException;
40e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.Inet4Address;
41e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.InetAddress;
420e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Piusimport java.util.Arrays;
43e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.util.BitSet;
44030c5debfefddf0512cd53fec48b269c08d9972eRoshan Piusimport java.util.HashMap;
452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/**
472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * The utility provides methods to write/parse section headers and write/parse values.
492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * This utility is designed for formatting the XML into the following format:
502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * <Document Header>
512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  <Section 1 Header>
522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 1>
532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 2>
542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   ...
552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Sub Section 1 Header>
562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 1>
572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 2>
582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    ...
592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   </Sub Section 1 Header>
602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  </Section 1 Header>
612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * </Document Header>
622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspublic class XmlUtil {
642b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    private static final String TAG = "WifiXmlUtil";
652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
662b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
67e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at a start tag or the end of document.
68e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
69052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
702b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
71e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoStartTag(XmlPullParser in)
722b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
73e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
74e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
75e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
76e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
77e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
78e33a4bb414892435c016486585c26022cafdab68Roshan Pius
79e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
80e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at an end tag or the end of document.
81e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
82052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
83e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
84e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoEndTag(XmlPullParser in)
85e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
86e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
87e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
88e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
89e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Start processing the XML stream at the document header.
942b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
97052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
982b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void gotoDocumentStart(XmlPullParser in, String headerName)
1002b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
1012b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.beginDocument(in, headerName);
1022b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1032b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
105c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header or indicate if there are no more sections.
106c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
107c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
108c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across sections if the ordering of sections are variable. The returned name
109c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * can be used to decide what section is next.
1102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
112c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param headerName An array of one string, used to return the name of the next section.
1132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param outerDepth Find section within this depth.
114c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
115052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
1162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
117c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static boolean gotoNextSectionOrEnd(
118c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String[] headerName, int outerDepth)
119c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throws XmlPullParserException, IOException {
120c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (XmlUtils.nextElementWithin(in, outerDepth)) {
121c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            headerName[0] = in.getName();
122c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            return true;
123c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        }
124c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        return false;
125c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    }
126c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius
127c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    /**
128c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header or indicate if there are no more sections.
129c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * If a section, exists ensure that the name matches the provided name.
130c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
131c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
132c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across repeated sections until the end.
133c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
134c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
135c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param expectedName expected name for the section header.
136c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param outerDepth   Find section within this depth.
137c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
138c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @throws XmlPullParserException if the section header name does not match |expectedName|,
139c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *                                or if parsing errors occur.
140c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     */
141c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static boolean gotoNextSectionWithNameOrEnd(
142c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String expectedName, int outerDepth)
1432b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
144c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        String[] headerName = new String[1];
145c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (gotoNextSectionOrEnd(in, headerName, outerDepth)) {
146c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            if (headerName[0].equals(expectedName)) {
1472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius                return true;
1482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            }
149c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throw new XmlPullParserException(
150c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    "Next section name does not match expected name: " + expectedName);
1512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        return false;
1532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
156c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Move the XML stream to the next section header and ensure that the name matches the provided
157c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * name.
158c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * The provided outerDepth is used to find sub sections within that depth.
159c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
160c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * Use this to move across sections if the ordering of sections are fixed.
161c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *
162c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
163c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param expectedName expected name for the section header.
164c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @param outerDepth   Find section within this depth.
165c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     * @throws XmlPullParserException if the section header name does not match |expectedName|,
166c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     *                                there are no more sections or if parsing errors occur.
167c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius     */
168c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    public static void gotoNextSectionWithName(
169c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            XmlPullParser in, String expectedName, int outerDepth)
170c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throws XmlPullParserException, IOException {
171c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        if (!gotoNextSectionWithNameOrEnd(in, expectedName, outerDepth)) {
172c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            throw new XmlPullParserException("Section not found. Expected: " + expectedName);
173c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        }
174c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    }
175c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius
176c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius    /**
177e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
178e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * and checks if it finds an end tag at the specified depth.
179e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
180e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
181e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
182e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
183052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
184e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
185e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
186e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
187c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        return !XmlUtils.nextElementWithin(in, sectionDepth);
188e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
189e33a4bb414892435c016486585c26022cafdab68Roshan Pius
190e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
191e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
192e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * value name in the string provided. This method reads the value contained in current start
193e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * tag.
194e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
195e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * an exception to indicate errors.
196e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
197e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in        XmlPullParser instance pointing to the XML stream.
198e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param valueName An array of one string, used to return the name attribute
199e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *                  of the value's tag.
200e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return value retrieved from the XML stream.
201052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
202e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
203e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
204e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
205e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = XmlUtils.readValueXml(in, valueName);
206e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
207e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // it to the end tag before returning from here.
208e33a4bb414892435c016486585c26022cafdab68Roshan Pius        gotoEndTag(in);
209e33a4bb414892435c016486585c26022cafdab68Roshan Pius        return value;
210e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
211e33a4bb414892435c016486585c26022cafdab68Roshan Pius
212e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
2132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
214e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * provided name. This method moves the stream to the next start tag and reads the value
215e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * contained in it.
2162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
2172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * an exception to indicate errors.
2182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2192b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in XmlPullParser instance pointing to the XML stream.
2202b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return value retrieved from the XML stream.
221052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if the value read does not match |expectedName|,
222052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     *                                or if parsing errors occur.
2232b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
224e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
2252b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
226e33a4bb414892435c016486585c26022cafdab68Roshan Pius        String[] valueName = new String[1];
227e33a4bb414892435c016486585c26022cafdab68Roshan Pius        XmlUtils.nextElement(in);
228e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = readCurrentValue(in, valueName);
229e33a4bb414892435c016486585c26022cafdab68Roshan Pius        if (valueName[0].equals(expectedName)) {
2302b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            return value;
2312b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
2322b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        throw new XmlPullParserException(
233e33a4bb414892435c016486585c26022cafdab68Roshan Pius                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
2342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document start with the provided document header name.
2382b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2392b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2402b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2412b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2422b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentStart(XmlSerializer out, String headerName)
243e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startDocument(null, true);
2452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document end with the provided document header name.
2502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentEnd(XmlSerializer out, String headerName)
255e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endDocument();
2582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section start header tag with the provided section name.
2622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2642b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2662b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionStart(XmlSerializer out, String headerName)
267e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2682b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2692b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2702b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2712b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2722b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section end header tag with the provided section name.
2732b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2742b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2752b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2762b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2772b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
278e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2792b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2802b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2812b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2822b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2832b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the value with the provided name in the XML stream using core XmlUtils.
2842b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2852b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out   XmlSerializer instance pointing to the XML stream.
2862b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param name  name of the value.
2872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param value value to be written.
2882b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextValue(XmlSerializer out, String name, Object value)
2902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
2912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.writeValueXml(value, name, out);
2922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
293e33a4bb414892435c016486585c26022cafdab68Roshan Pius
294e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
2955d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * Utility class to serialize and deseriaize {@link WifiConfiguration} object to XML &
2965d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * vice versa.
2975d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
2985d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * {@link com.android.server.wifi.WifiBackupRestore} modules.
299e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
300e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
301e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The parse method is written so that any element added/deleted in future revisions can
302e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * be easily handled.
303e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
304e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class WifiConfigurationXmlUtil {
305e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
306e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to WifiConfiguration object elements.
307e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
308e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SSID = "SSID";
309e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_BSSID = "BSSID";
310e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
311e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
312e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
313e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
314e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
315e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
316e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
317e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
318e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SHARED = "Shared";
319030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_FQDN = "FQDN";
320030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_PROVIDER_FRIENDLY_NAME = "ProviderFriendlyName";
321030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LINKED_NETWORKS_LIST = "LinkedNetworksList";
322030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_DEFAULT_GW_MAC_ADDRESS = "DefaultGwMacAddress";
323030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
324030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NO_INTERNET_ACCESS_EXPECTED = "NoInternetAccessExpected";
325030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USER_APPROVED = "UserApproved";
326030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_METERED_HINT = "MeteredHint";
327030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores";
328030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation";
329e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
3302fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius        public static final String XML_TAG_CREATOR_NAME = "CreatorName";
331030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_CREATION_TIME = "CreationTime";
332030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid";
333030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName";
334030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid";
335e33a4bb414892435c016486585c26022cafdab68Roshan Pius
336e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
337e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write WepKeys to the XML stream.
338e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
33906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
34006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * XmlUtils serialization doesn't handle this array of nulls well .
34106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * So, write empty strings if some of the keys are not initialized and null if all of
34206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * the elements are empty.
343e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
344e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
345e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
34606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            String[] wepKeysToWrite = new String[wepKeys.length];
34706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            boolean hasWepKey = false;
34806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
34906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeys[i] == null) {
35006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = new String();
35106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
35206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = wepKeys[i];
35306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    hasWepKey = true;
35406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                }
35506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
35606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (hasWepKey) {
35706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
358e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
359e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
360e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
361e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
362e33a4bb414892435c016486585c26022cafdab68Roshan Pius
363e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
364e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements that are common for backup & config store to the
365e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
366e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
367e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
368e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
369e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
370c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeCommonElementsToXml(
371c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, WifiConfiguration configuration)
372e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
373e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
374e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
375e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
376e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
377e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeWepKeysToXml(out, configuration.wepKeys);
378e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
379e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
380e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
381e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_KEY_MGMT,
382e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedKeyManagement.toByteArray());
383e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
384e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_PROTOCOLS,
385e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedProtocols.toByteArray());
386e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
387e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
388e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedAuthAlgorithms.toByteArray());
389e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
390e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
391e33a4bb414892435c016486585c26022cafdab68Roshan Pius
392e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
393e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for backup from the provided Configuration to the
394e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
395e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is a subset of the elements serialized for config store.
396e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
397e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
398e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
399e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
400c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)
401e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
402c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            writeCommonElementsToXml(out, configuration);
403e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
404e33a4bb414892435c016486585c26022cafdab68Roshan Pius
405e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
406e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for config store from the provided Configuration
407e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * to the XML stream.
408642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
409642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
410642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
411e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
412c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXmlForConfigStore(
413c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, WifiConfiguration configuration)
414e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
415c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius            writeCommonElementsToXml(out, configuration);
416030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
417030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
418030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName);
419030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
420030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations);
421030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
422030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress);
423030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
424030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess);
425030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
426030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED,
427030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    configuration.noInternetAccessExpected);
428030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved);
429030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint);
430030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
431030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores);
432030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation);
4332fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
4342fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName);
435030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime);
436030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid);
437030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName);
438030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid);
439e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
440e33a4bb414892435c016486585c26022cafdab68Roshan Pius
441e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
44206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * Populate wepKeys array elements only if they were non-empty in the backup data.
4432fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         *
44406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * @throws XmlPullParserException if parsing errors occur.
445e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
446e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
447e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
448e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] wepKeysInData = (String[]) value;
44906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData == null) {
45006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                return;
45106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
45206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData.length != wepKeys.length) {
45306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                throw new XmlPullParserException(
45406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                        "Invalid Wep Keys length: " + wepKeysInData.length);
45506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
45606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
45706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeysInData[i].isEmpty()) {
45806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeys[i] = null;
45906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
460e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    wepKeys[i] = wepKeysInData[i];
461e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
462e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
463e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
464e33a4bb414892435c016486585c26022cafdab68Roshan Pius
465e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
4665d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the configuration data elements from the provided XML stream to a
4675d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * WifiConfiguration object.
468e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is used for parsing both backup data and config store data. Looping through
469e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * the tags make it easy to add or remove elements in the future versions if needed.
470e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
471e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
472e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
4732fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
4742fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * null otherwise.
475e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
476c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static Pair<String, WifiConfiguration> parseFromXml(
4772fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                XmlPullParser in, int outerTagDepth)
478e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
479e33a4bb414892435c016486585c26022cafdab68Roshan Pius            WifiConfiguration configuration = new WifiConfiguration();
480e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String configKeyInData = null;
481e33a4bb414892435c016486585c26022cafdab68Roshan Pius
482e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
483e33a4bb414892435c016486585c26022cafdab68Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
484e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] valueName = new String[1];
485e33a4bb414892435c016486585c26022cafdab68Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
486e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (valueName[0] == null) {
487c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Missing value name");
488e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
489e33a4bb414892435c016486585c26022cafdab68Roshan Pius                switch (valueName[0]) {
490e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CONFIG_KEY:
491e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configKeyInData = (String) value;
492e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
493e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SSID:
494e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.SSID = (String) value;
495e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
496e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_BSSID:
497e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.BSSID = (String) value;
498e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
499e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_PRE_SHARED_KEY:
500e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.preSharedKey = (String) value;
501e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
502e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_KEYS:
503e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
504e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
505e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_TX_KEY_INDEX:
506e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.wepTxKeyIndex = (int) value;
507e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
508e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_HIDDEN_SSID:
509e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.hiddenSSID = (boolean) value;
510e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
511e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_KEY_MGMT:
512e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedKeyMgmt = (byte[]) value;
513e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
514e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
515e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_PROTOCOLS:
516e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedProtocols = (byte[]) value;
517e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
518e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
519e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_AUTH_ALGOS:
520e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedAuthAlgorithms = (byte[]) value;
521e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
522e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
523e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SHARED:
524e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.shared = (boolean) value;
525e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
526030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_FQDN:
527030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.FQDN = (String) value;
528030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
529030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
530030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.providerFriendlyName = (String) value;
531030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
532030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LINKED_NETWORKS_LIST:
533030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
534030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
535030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
536030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.defaultGwMacAddress = (String) value;
537030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
538030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
539030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.validatedInternetAccess = (boolean) value;
540030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
541030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
542030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.noInternetAccessExpected = (boolean) value;
543030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
544030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USER_APPROVED:
545030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.userApproved = (int) value;
546030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
547030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_METERED_HINT:
548030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.meteredHint = (boolean) value;
549030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
550030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USE_EXTERNAL_SCORES:
551030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.useExternalScores = (boolean) value;
552030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
553030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NUM_ASSOCIATION:
554030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.numAssociation = (int) value;
555030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
556e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CREATOR_UID:
557e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.creatorUid = (int) value;
558e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
5592fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                    case XML_TAG_CREATOR_NAME:
5602fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        configuration.creatorName = (String) value;
5612fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        break;
562030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_CREATION_TIME:
563030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.creationTime = (String) value;
564030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
565030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_UID:
566030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateUid = (int) value;
567030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
568030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_NAME:
569030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateName = (String) value;
570030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
571030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_CONNECT_UID:
572030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastConnectUid = (int) value;
573030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
574e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    default:
575c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                        throw new XmlPullParserException(
576c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                                "Unknown value name found: " + valueName[0]);
577e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
578e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
5792fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            return Pair.create(configKeyInData, configuration);
580e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
581e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
582e33a4bb414892435c016486585c26022cafdab68Roshan Pius
583e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
5845d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * Utility class to serialize and deseriaize {@link IpConfiguration} object to XML & vice versa.
5855d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
5865d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * {@link com.android.server.wifi.WifiBackupRestore} modules.
587e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
588e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class IpConfigurationXmlUtil {
589e33a4bb414892435c016486585c26022cafdab68Roshan Pius
590e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
591e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to IpConfiguration object elements.
592e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
593e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
594e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
595e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
596e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
597e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
598e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
599e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
600e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
601e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
602e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
603e33a4bb414892435c016486585c26022cafdab68Roshan Pius
604e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
605e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the static IP configuration data elements to XML stream.
606e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
607c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        private static void writeStaticIpConfigurationToXml(
608c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                XmlSerializer out, StaticIpConfiguration staticIpConfiguration)
609e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
610e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.ipAddress != null) {
611e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
612e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS,
613e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
614e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
615e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH,
616e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getPrefixLength());
617e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
618e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
619e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS, null);
620e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
621e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
622e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
623e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.gateway != null) {
624e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
625e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS,
626e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.gateway.getHostAddress());
627e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
628e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
629e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS, null);
630e33a4bb414892435c016486585c26022cafdab68Roshan Pius
631e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
632e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.dnsServers != null) {
633e33a4bb414892435c016486585c26022cafdab68Roshan Pius                // Create a string array of DNS server addresses
634e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
635e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int dnsServerIdx = 0;
636e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
637e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
638e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
639e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
640e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
641e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
642e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
643e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
644e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
645e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
646e33a4bb414892435c016486585c26022cafdab68Roshan Pius
647e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
648e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the IP configuration data elements from the provided Configuration to the XML
649e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * stream.
650642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
651642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out             XmlSerializer instance pointing to the XML stream.
652642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param ipConfiguration IpConfiguration object to be serialized.
653e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
654c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static void writeToXml(XmlSerializer out, IpConfiguration ipConfiguration)
655e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
656e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write IP assignment settings
657e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
658e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.ipAssignment.toString());
659e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.ipAssignment) {
660e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
661e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    writeStaticIpConfigurationToXml(
662e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, ipConfiguration.getStaticIpConfiguration());
663e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
664e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
665e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
666e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
667e33a4bb414892435c016486585c26022cafdab68Roshan Pius
668e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write proxy settings
669e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
670e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_PROXY_SETTINGS,
671e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.proxySettings.toString());
672e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.proxySettings) {
673e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
674e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
675e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_HOST,
676e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getHost());
677e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
678e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PORT,
679e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPort());
680e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
681e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_EXCLUSION_LIST,
682e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getExclusionListAsString());
683e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
684e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
685e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
686e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PAC_FILE,
687e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPacFileUrl().toString());
688e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
689e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
690e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
691e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
692e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
693e33a4bb414892435c016486585c26022cafdab68Roshan Pius
694e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
695e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parse out the static IP configuration from the XML stream.
696e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
697e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
698e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
699e33a4bb414892435c016486585c26022cafdab68Roshan Pius            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
700e33a4bb414892435c016486585c26022cafdab68Roshan Pius
701e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String linkAddressString =
702e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
703e33a4bb414892435c016486585c26022cafdab68Roshan Pius            Integer linkPrefixLength =
704e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
705e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (linkAddressString != null && linkPrefixLength != null) {
706e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress linkAddress = new LinkAddress(
707e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(linkAddressString),
708e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        linkPrefixLength);
709e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (linkAddress.getAddress() instanceof Inet4Address) {
710e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.ipAddress = linkAddress;
711e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
712e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
713e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
714e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
715e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String gatewayAddressString =
716e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
717e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (gatewayAddressString != null) {
718e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress dest = null;
719e33a4bb414892435c016486585c26022cafdab68Roshan Pius                InetAddress gateway =
720e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(gatewayAddressString);
721e33a4bb414892435c016486585c26022cafdab68Roshan Pius                RouteInfo route = new RouteInfo(dest, gateway);
722e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (route.isIPv4Default()) {
723e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.gateway = gateway;
724e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
725e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 default route: " + route);
726e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
727e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
728e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] dnsServerAddressesString =
729e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
730e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (dnsServerAddressesString != null) {
731e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (String dnsServerAddressString : dnsServerAddressesString) {
732e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    InetAddress dnsServerAddress =
733e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
734e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
735e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
736e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
737e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return staticIpConfiguration;
738e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
739e33a4bb414892435c016486585c26022cafdab68Roshan Pius
740e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
7415d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the IP configuration data elements from the provided XML stream to an
7425d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * IpConfiguration object.
743e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
744e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
745e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
746e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @return IpConfiguration object if parsing is successful, null otherwise.
747e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
748c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static IpConfiguration parseFromXml(XmlPullParser in, int outerTagDepth)
749e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
750e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpConfiguration ipConfiguration = new IpConfiguration();
751e33a4bb414892435c016486585c26022cafdab68Roshan Pius
752e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the IP assignment info first.
753e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String ipAssignmentString =
754e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
755e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
756e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setIpAssignment(ipAssignment);
757e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipAssignment) {
758e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
759e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
760e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
761e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case DHCP:
762e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
763e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
764e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
765c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment);
766e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
767e33a4bb414892435c016486585c26022cafdab68Roshan Pius
768e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the proxy settings next.
769e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String proxySettingsString =
770e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
771e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
772e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setProxySettings(proxySettings);
773e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (proxySettings) {
774e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
775e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyHost =
776e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
777e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    int proxyPort =
778e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
779e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyExclusionList =
780e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(
781e33a4bb414892435c016486585c26022cafdab68Roshan Pius                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
782e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(
783e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
784e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
785e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
786e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyPacFile =
787e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
788e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
789e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
790e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case NONE:
791e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
792e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
793e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
794c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException(
795c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                            "Unknown proxy settings type: " + proxySettings);
796e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
797e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return ipConfiguration;
798e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
799e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
8005d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8015d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    /**
8025d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * Utility class to serialize and deseriaize {@link NetworkSelectionStatus} object to XML &
8035d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
8045d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius     */
8055d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    public static class NetworkSelectionStatusXmlUtil {
8065d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8075d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
8085d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * List of XML tags corresponding to NetworkSelectionStatus object elements.
8095d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
8105d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_SELECTION_STATUS = "SelectionStatus";
8115d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_DISABLE_REASON = "DisableReason";
8125d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_CONNECT_CHOICE = "ConnectChoice";
8135d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_CONNECT_CHOICE_TIMESTAMP = "ConnectChoiceTimeStamp";
8145d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        public static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
8155d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8165d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
8175d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Write the NetworkSelectionStatus data elements from the provided status to the XML
8185d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * stream.
819642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
8200e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius         * @param out             XmlSerializer instance pointing to the XML stream.
8210e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius         * @param selectionStatus NetworkSelectionStatus object to be serialized.
8225d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
8230e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius        public static void writeToXml(XmlSerializer out, NetworkSelectionStatus selectionStatus)
8245d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                throws XmlPullParserException, IOException {
8255d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            XmlUtil.writeNextValue(
8260e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_SELECTION_STATUS, selectionStatus.getNetworkStatusString());
8270e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(
8280e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_DISABLE_REASON, selectionStatus.getNetworkDisableReasonString());
8290e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONNECT_CHOICE, selectionStatus.getConnectChoice());
8305d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            XmlUtil.writeNextValue(
8310e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_CONNECT_CHOICE_TIMESTAMP,
8320e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    selectionStatus.getConnectChoiceTimestamp());
8330e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            XmlUtil.writeNextValue(
8340e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    out, XML_TAG_HAS_EVER_CONNECTED, selectionStatus.getHasEverConnected());
8355d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        }
8365d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8375d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        /**
8385d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * Parses the NetworkSelectionStatus data elements from the provided XML stream to a
8395d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * NetworkSelectionStatus object.
8405d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         *
8415d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
8425d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
8435d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         * @return NetworkSelectionStatus object if parsing is successful, null otherwise.
8445d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius         */
845c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius        public static NetworkSelectionStatus parseFromXml(XmlPullParser in, int outerTagDepth)
8465d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                throws XmlPullParserException, IOException {
8470e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            NetworkSelectionStatus selectionStatus = new NetworkSelectionStatus();
8480e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            String statusString = "";
8490e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            String disableReasonString = "";
8505d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius
8515d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
8525d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
8535d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                String[] valueName = new String[1];
8545d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
8555d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                if (valueName[0] == null) {
856c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                    throw new XmlPullParserException("Missing value name");
8575d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                }
8585d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                switch (valueName[0]) {
8595d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_SELECTION_STATUS:
8600e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        statusString = (String) value;
8615d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
8625d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_DISABLE_REASON:
8630e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        disableReasonString = (String) value;
8645d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
8655d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_CONNECT_CHOICE:
8660e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setConnectChoice((String) value);
8675d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
8685d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_CONNECT_CHOICE_TIMESTAMP:
8690e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setConnectChoiceTimestamp((long) value);
8705d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
8715d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    case XML_TAG_HAS_EVER_CONNECTED:
8720e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                        selectionStatus.setHasEverConnected((boolean) value);
8735d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                        break;
8745d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                    default:
875c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                        throw new XmlPullParserException(
876c00a9331ab2a51babc3c3acd69f44be3d341c4b9Roshan Pius                                "Unknown value name found: " + valueName[0]);
8775d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius                }
8785d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius            }
8790e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // Now figure out the network selection status codes from |selectionStatusString| &
8800e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // |disableReasonString|.
8810e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            int status =
8820e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_STATUS)
8830e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                            .indexOf(statusString);
8840e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            int disableReason =
8850e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_DISABLE_REASON)
8860e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                            .indexOf(disableReasonString);
8870e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius
8880e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // If either of the above codes are invalid or if the network was temporarily disabled
8890e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // (blacklisted), restore the status as enabled. We don't want to persist blacklists
8900e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            // across reboots.
8910e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            if (status == -1 || disableReason == -1 ||
8920e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                    status == NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
8930e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                status = NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
8940e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius                disableReason = NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
8950e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            }
8960e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            selectionStatus.setNetworkSelectionStatus(status);
8970e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            selectionStatus.setNetworkSelectionDisableReason(disableReason);
8980e2540a1c1ba3c541a229b039a90789f93c41ee7Roshan Pius            return selectionStatus;
8995d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius        }
9005d3609b1931180c37d7292619146ad7d33df9a21Roshan Pius    }
901642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
902642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    /**
903642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     * Utility class to serialize and deseriaize {@link WifiEnterpriseConfig} object to XML &
904642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
905642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius     */
906642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    public static class WifiEnterpriseConfigXmlUtil {
907642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
908642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
909642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * List of XML tags corresponding to WifiEnterpriseConfig object elements.
910642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
911642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_IDENTITY = "Identity";
912642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ANON_IDENTITY = "AnonIdentity";
913642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PASSWORD = "Password";
914642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CLIENT_CERT = "ClientCert";
915642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CA_CERT = "CaCert";
916642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_SUBJECT_MATCH = "SubjectMatch";
917642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ENGINE = "Engine";
918642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ENGINE_ID = "EngineId";
919642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PRIVATE_KEY_ID = "PrivateKeyId";
920642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_ALT_SUBJECT_MATCH = "AltSubjectMatch";
921642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_DOM_SUFFIX_MATCH = "DomSuffixMatch";
922642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_CA_PATH = "CaPath";
923642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_EAP_METHOD = "EapMethod";
924642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static final String XML_TAG_PHASE2_METHOD = "Phase2Method";
925642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
926642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
927642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * Write the WifiEnterpriseConfig data elements from the provided config to the XML
928642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * stream.
929642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
930642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param out              XmlSerializer instance pointing to the XML stream.
931642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param enterpriseConfig WifiEnterpriseConfig object to be serialized.
932642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
933642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)
934642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                throws XmlPullParserException, IOException {
935642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IDENTITY,
936d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY));
937642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY,
938d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY));
939642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PASSWORD,
940d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY));
941642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT,
942d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY));
943642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CA_CERT,
944d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY));
945642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SUBJECT_MATCH,
946d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY));
947642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ENGINE,
948d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY));
949642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ENGINE_ID,
950d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY));
951642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRIVATE_KEY_ID,
952d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY));
953642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_ALT_SUBJECT_MATCH,
954d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY));
955642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_DOM_SUFFIX_MATCH,
956d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY));
957642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CA_PATH,
958d83ef7d8c4948afc328d8ef0e746b32c195f271eRoshan Pius                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY));
959642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod());
960642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method());
961642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        }
962642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
963642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        /**
964642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object.
965642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         *
966642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
967642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
968642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         * @return WifiEnterpriseConfig object if parsing is successful, null otherwise.
969642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius         */
970642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth)
971642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                throws XmlPullParserException, IOException {
972642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
973642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius
974642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
975642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
976642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                String[] valueName = new String[1];
977642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
978642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                if (valueName[0] == null) {
979642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    throw new XmlPullParserException("Missing value name");
980642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                }
981642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                switch (valueName[0]) {
982642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_IDENTITY:
983642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
984642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
985642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
986642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ANON_IDENTITY:
987642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
988642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
989642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
990642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PASSWORD:
991642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
992642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
993642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
994642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CLIENT_CERT:
995642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
996642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
997642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
998642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CA_CERT:
999642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1000642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
1001642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1002642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_SUBJECT_MATCH:
1003642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1004642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
1005642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1006642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ENGINE:
1007642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1008642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ENGINE_KEY, (String) value);
1009642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1010642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ENGINE_ID:
1011642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1012642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
1013642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1014642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PRIVATE_KEY_ID:
1015642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1016642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
1017642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1018642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_ALT_SUBJECT_MATCH:
1019642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1020642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
1021642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1022642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_DOM_SUFFIX_MATCH:
1023642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1024642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
1025642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1026642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_CA_PATH:
1027642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setFieldValue(
1028642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
1029642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1030642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_EAP_METHOD:
1031642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setEapMethod((int) value);
1032642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1033642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    case XML_TAG_PHASE2_METHOD:
1034642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        enterpriseConfig.setPhase2Method((int) value);
1035642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        break;
1036642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                    default:
1037642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                        throw new XmlPullParserException(
1038642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                                "Unknown value name found: " + valueName[0]);
1039642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius                }
1040642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            }
1041642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius            return enterpriseConfig;
1042642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius        }
1043642b0bb43ed856bac0503d3169d67026de2c1b02Roshan Pius    }
10442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius}
10452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1046