/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.util.Log;
import android.util.Pair;

import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Parser for major version 1 of WiFi backup data.
 * Contains whitelists of tags for WifiConfiguration and IpConfiguration sections for each of
 * the minor versions.
 *
 * Overall structure of the major version 1 XML schema:
 * <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
 * <WifiConfigStore>
 *  <float name="Version" value="1.0" />
 *  <NetworkList>
 *   <Network>
 *    <WifiConfiguration>
 *     <string name="ConfigKey">value</string>
 *     <string name="SSID">value</string>
 *     <string name="BSSID" />value</string>
 *     <string name="PreSharedKey" />value</string>
 *     <string-array name="WEPKeys" num="4">
 *      <item value="WifiConfigStoreWep1" />
 *      <item value="WifiConfigStoreWep2" />
 *      <item value="WifiConfigStoreWep3" />
 *      <item value="WifiConfigStoreWep3" />
 *     </string-array>
 *     ... (other supported tag names in minor version 1: "WEPTxKeyIndex", "HiddenSSID",
 *          "RequirePMF", "AllowedKeyMgmt", "AllowedProtocols", "AllowedAuthAlgos",
 *          "AllowedGroupCiphers", "AllowedPairwiseCiphers", "Shared")
 *    </WifiConfiguration>
 *    <IpConfiguration>
 *     <string name="IpAssignment">value</string>
 *     <string name="ProxySettings">value</string>
 *      ... (other supported tag names in minor version 1: "LinkAddress", "LinkPrefixLength",
 *           "GatewayAddress", "DNSServers", "ProxyHost", "ProxyPort", "ProxyPac",
 *           "ProxyExclusionList")
 *    </IpConfiguration>
 *   </Network>
 *   <Network>
 *    ... (format as above)
 *   </Network>
 *  </NetworkList>
 * </WifiConfigStore>
 */
class WifiBackupDataV1Parser implements WifiBackupDataParser {

    private static final String TAG = "WifiBackupDataV1Parser";

    private static final int HIGHEST_SUPPORTED_MINOR_VERSION = 1;

    // List of tags supported for <WifiConfiguration> section in minor version 0
    private static final Set<String> WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS =
            new HashSet<String>(Arrays.asList(new String[] {
                WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY,
                WifiConfigurationXmlUtil.XML_TAG_SSID,
                WifiConfigurationXmlUtil.XML_TAG_BSSID,
                WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY,
                WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS,
                WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX,
                WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID,
                WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF,
                WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT,
                WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS,
                WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS,
                WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS,
                WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS,
                WifiConfigurationXmlUtil.XML_TAG_SHARED,
            }));

    // List of tags supported for <WifiConfiguration> section in minor version 1
    private static final Set<String> WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS =
            new HashSet<String>() {{
                addAll(WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS);
                add(WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE);
            }};

    // List of tags supported for <IpConfiguration> section in minor version 0 & 1
    private static final Set<String> IP_CONFIGURATION_MINOR_V0_V1_SUPPORTED_TAGS =
            new HashSet<String>(Arrays.asList(new String[] {
                IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT,
                IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS,
                IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH,
                IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS,
                IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES,
                IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS,
                IpConfigurationXmlUtil.XML_TAG_PROXY_HOST,
                IpConfigurationXmlUtil.XML_TAG_PROXY_PORT,
                IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST,
                IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE,
            }));

    public List<WifiConfiguration> parseNetworkConfigurationsFromXml(XmlPullParser in,
            int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException {
        // clamp down the minorVersion to the highest one that this parser version supports
        if (minorVersion > HIGHEST_SUPPORTED_MINOR_VERSION) {
            minorVersion = HIGHEST_SUPPORTED_MINOR_VERSION;
        }
        // Find the configuration list section.
        XmlUtil.gotoNextSectionWithName(in, WifiBackupRestore.XML_TAG_SECTION_HEADER_NETWORK_LIST,
                outerTagDepth);
        // Find all the configurations within the configuration list section.
        int networkListTagDepth = outerTagDepth + 1;
        List<WifiConfiguration> configurations = new ArrayList<>();
        while (XmlUtil.gotoNextSectionWithNameOrEnd(
                in, WifiBackupRestore.XML_TAG_SECTION_HEADER_NETWORK, networkListTagDepth)) {
            WifiConfiguration configuration =
                    parseNetworkConfigurationFromXml(in, minorVersion, networkListTagDepth);
            if (configuration != null) {
                Log.v(TAG, "Parsed Configuration: " + configuration.configKey());
                configurations.add(configuration);
            }
        }
        return configurations;
    }

    /**
     * Parses the configuration data elements from the provided XML stream to a Configuration.
     *
     * @param in            XmlPullParser instance pointing to the XML stream.
     * @param minorVersion  minor version number parsed from incoming data.
     * @param outerTagDepth depth of the outer tag in the XML document.
     * @return WifiConfiguration object if parsing is successful, null otherwise.
     */
    private WifiConfiguration parseNetworkConfigurationFromXml(XmlPullParser in, int minorVersion,
            int outerTagDepth) throws XmlPullParserException, IOException {
        WifiConfiguration configuration = null;
        int networkTagDepth = outerTagDepth + 1;
        // Retrieve WifiConfiguration object first.
        XmlUtil.gotoNextSectionWithName(
                in, WifiBackupRestore.XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION,
                networkTagDepth);
        int configTagDepth = networkTagDepth + 1;
        configuration = parseWifiConfigurationFromXml(in, configTagDepth, minorVersion);
        if (configuration == null) {
            return null;
        }
        // Now retrieve any IP configuration info.
        XmlUtil.gotoNextSectionWithName(
                in, WifiBackupRestore.XML_TAG_SECTION_HEADER_IP_CONFIGURATION, networkTagDepth);
        IpConfiguration ipConfiguration = parseIpConfigurationFromXml(in, configTagDepth,
                minorVersion);
        configuration.setIpConfiguration(ipConfiguration);
        return configuration;
    }

    /**
     * Helper method to parse the WifiConfiguration object.
     */
    private WifiConfiguration parseWifiConfigurationFromXml(XmlPullParser in,
            int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException {
        Pair<String, WifiConfiguration> parsedConfig =
                parseWifiConfigurationFromXmlInternal(in, outerTagDepth, minorVersion);
        if (parsedConfig == null || parsedConfig.first == null || parsedConfig.second == null) {
            return null;
        }
        String configKeyParsed = parsedConfig.first;
        WifiConfiguration configuration = parsedConfig.second;
        String configKeyCalculated = configuration.configKey();
        if (!configKeyParsed.equals(configKeyCalculated)) {
            // configKey is not part of the SDK. So, we can't expect this to be the same
            // across OEM's. Just log a warning & continue.
            Log.w(TAG, "Configuration key does not match. Retrieved: " + configKeyParsed
                    + ", Calculated: " + configKeyCalculated);
        }
        return configuration;
    }

    /**
     * Helper method to mask out any invalid data in parsed WifiConfiguration.
     *
     * This is a compatibility layer added to the parsing logic to try and weed out any known
     * issues in the backup data format from other OEM's.
     */
    private static void clearAnyKnownIssuesInParsedConfiguration(WifiConfiguration config) {
        /**
         * Fix for b/73987207. Clear any invalid bits in the bitsets.
         */
        // |allowedKeyManagement|
        if (config.allowedKeyManagement.length()
                > WifiConfiguration.KeyMgmt.strings.length) {
            config.allowedKeyManagement.clear(
                    WifiConfiguration.KeyMgmt.strings.length,
                    config.allowedKeyManagement.length());
        }
        // |allowedProtocols|
        if (config.allowedProtocols.length()
                > WifiConfiguration.Protocol.strings.length) {
            config.allowedProtocols.clear(
                    WifiConfiguration.Protocol.strings.length,
                    config.allowedProtocols.length());
        }
        // |allowedAuthAlgorithms|
        if (config.allowedAuthAlgorithms.length()
                > WifiConfiguration.AuthAlgorithm.strings.length) {
            config.allowedAuthAlgorithms.clear(
                    WifiConfiguration.AuthAlgorithm.strings.length,
                    config.allowedAuthAlgorithms.length());
        }
        // |allowedGroupCiphers|
        if (config.allowedGroupCiphers.length()
                > WifiConfiguration.GroupCipher.strings.length) {
            config.allowedGroupCiphers.clear(
                    WifiConfiguration.GroupCipher.strings.length,
                    config.allowedGroupCiphers.length());
        }
        // |allowedPairwiseCiphers|
        if (config.allowedPairwiseCiphers.length()
                > WifiConfiguration.PairwiseCipher.strings.length) {
            config.allowedPairwiseCiphers.clear(
                    WifiConfiguration.PairwiseCipher.strings.length,
                    config.allowedPairwiseCiphers.length());
        }
        // Add any other fixable issues discovered from other OEM's here.
    }

    /**
     * Parses the configuration data elements from the provided XML stream to a
     * WifiConfiguration object.
     * Looping through the tags makes it easy to add elements in the future minor versions if
     * needed. Unsupported elements will be ignored.
     *
     * @param in            XmlPullParser instance pointing to the XML stream.
     * @param outerTagDepth depth of the outer tag in the XML document.
     * @param minorVersion  minor version number parsed from incoming data.
     * @return Pair<Config key, WifiConfiguration object> if parsing is successful, null otherwise.
     */
    private static Pair<String, WifiConfiguration> parseWifiConfigurationFromXmlInternal(
            XmlPullParser in, int outerTagDepth, int minorVersion)
            throws XmlPullParserException, IOException {
        WifiConfiguration configuration = new WifiConfiguration();
        String configKeyInData = null;
        Set<String> supportedTags = getSupportedWifiConfigurationTags(minorVersion);

        // Loop through and parse out all the elements from the stream within this section.
        while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
            String[] valueName = new String[1];
            Object value = XmlUtil.readCurrentValue(in, valueName);
            String tagName = valueName[0];
            if (tagName == null) {
                throw new XmlPullParserException("Missing value name");
            }

            // ignore the tags that are not supported up until the current minor version
            if (!supportedTags.contains(tagName)) {
                Log.w(TAG, "Unsupported tag + \"" + tagName + "\" found in <WifiConfiguration>"
                        + " section, ignoring.");
                continue;
            }

            // note: the below switch case list should contain all tags supported up until the
            // highest minor version supported by this parser
            switch (tagName) {
                case WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY:
                    configKeyInData = (String) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_SSID:
                    configuration.SSID = (String) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_BSSID:
                    configuration.BSSID = (String) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY:
                    configuration.preSharedKey = (String) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS:
                    populateWepKeysFromXmlValue(value, configuration.wepKeys);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX:
                    configuration.wepTxKeyIndex = (int) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID:
                    configuration.hiddenSSID = (boolean) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF:
                    configuration.requirePMF = (boolean) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT:
                    byte[] allowedKeyMgmt = (byte[]) value;
                    configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS:
                    byte[] allowedProtocols = (byte[]) value;
                    configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS:
                    byte[] allowedAuthAlgorithms = (byte[]) value;
                    configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS:
                    byte[] allowedGroupCiphers = (byte[]) value;
                    configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
                    byte[] allowedPairwiseCiphers = (byte[]) value;
                    configuration.allowedPairwiseCiphers =
                            BitSet.valueOf(allowedPairwiseCiphers);
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_SHARED:
                    configuration.shared = (boolean) value;
                    break;
                case WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE:
                    configuration.meteredOverride = (int) value;
                    break;
                default:
                    // should never happen, since other tags are filtered out earlier
                    throw new XmlPullParserException(
                            "Unknown value name found: " + valueName[0]);
            }
        }
        clearAnyKnownIssuesInParsedConfiguration(configuration);
        return Pair.create(configKeyInData, configuration);
    }

    /**
     * Returns a set of supported tags of <WifiConfiguration> element for all minor versions of
     * this major version up to and including the specified minorVersion (only adding tags is
     * supported in minor versions, removal or changing the meaning of tags requires bumping
     * the major version and reseting the minor to 0).
     *
     * @param minorVersion  minor version number parsed from incoming data.
     */
    private static Set<String> getSupportedWifiConfigurationTags(int minorVersion) {
        switch (minorVersion) {
            case 0:
                return WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS;
            case 1:
                return WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS;
            default:
                Log.e(TAG, "Invalid minorVersion: " + minorVersion);
                return Collections.<String>emptySet();
        }
    }

    /**
     * Populate wepKeys array elements only if they were non-empty in the backup data.
     *
     * @throws XmlPullParserException if parsing errors occur.
     */
    private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
            throws XmlPullParserException, IOException {
        String[] wepKeysInData = (String[]) value;
        if (wepKeysInData == null) {
            return;
        }
        if (wepKeysInData.length != wepKeys.length) {
            throw new XmlPullParserException(
                    "Invalid Wep Keys length: " + wepKeysInData.length);
        }
        for (int i = 0; i < wepKeys.length; i++) {
            if (wepKeysInData[i].isEmpty()) {
                wepKeys[i] = null;
            } else {
                wepKeys[i] = wepKeysInData[i];
            }
        }
    }

    /**
     * Parses the IP configuration data elements from the provided XML stream to an
     * IpConfiguration object.
     *
     * @param in            XmlPullParser instance pointing to the XML stream.
     * @param outerTagDepth depth of the outer tag in the XML document.
     * @param minorVersion  minor version number parsed from incoming data.
     * @return IpConfiguration object if parsing is successful, null otherwise.
     */
    private static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in,
            int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException {
        // First parse *all* of the tags in <IpConfiguration> section
        Set<String> supportedTags = getSupportedIpConfigurationTags(minorVersion);

        String ipAssignmentString = null;
        String linkAddressString = null;
        Integer linkPrefixLength = null;
        String gatewayAddressString = null;
        String[] dnsServerAddressesString = null;
        String proxySettingsString = null;
        String proxyHost = null;
        int proxyPort = -1;
        String proxyExclusionList = null;
        String proxyPacFile = null;

        // Loop through and parse out all the elements from the stream within this section.
        while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
            String[] valueName = new String[1];
            Object value = XmlUtil.readCurrentValue(in, valueName);
            String tagName = valueName[0];
            if (tagName == null) {
                throw new XmlPullParserException("Missing value name");
            }

            // ignore the tags that are not supported up until the current minor version
            if (!supportedTags.contains(tagName)) {
                Log.w(TAG, "Unsupported tag + \"" + tagName + "\" found in <IpConfiguration>"
                        + " section, ignoring.");
                continue;
            }

            // note: the below switch case list should contain all tags supported up until the
            // highest minor version supported by this parser
            // should any tags be added in next minor versions, conditional processing of them
            // also needs to be added in the below code (processing into IpConfiguration object)
            switch (tagName) {
                case IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT:
                    ipAssignmentString = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS:
                    linkAddressString = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH:
                    linkPrefixLength = (Integer) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS:
                    gatewayAddressString = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES:
                    dnsServerAddressesString = (String[]) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS:
                    proxySettingsString = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_PROXY_HOST:
                    proxyHost = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_PROXY_PORT:
                    proxyPort = (int) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST:
                    proxyExclusionList = (String) value;
                    break;
                case IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE:
                    proxyPacFile = (String) value;
                    break;
                default:
                    // should never happen, since other tags are filtered out earlier
                    throw new XmlPullParserException(
                            "Unknown value name found: " + valueName[0]);
            }
        }

        // Now process the values into IpConfiguration object
        IpConfiguration ipConfiguration = new IpConfiguration();
        if (ipAssignmentString == null) {
            throw new XmlPullParserException("IpAssignment was missing in IpConfiguration section");
        }
        IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
        ipConfiguration.setIpAssignment(ipAssignment);
        switch (ipAssignment) {
            case STATIC:
                StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
                if (linkAddressString != null && linkPrefixLength != null) {
                    LinkAddress linkAddress = new LinkAddress(
                            NetworkUtils.numericToInetAddress(linkAddressString), linkPrefixLength);
                    if (linkAddress.getAddress() instanceof Inet4Address) {
                        staticIpConfiguration.ipAddress = linkAddress;
                    } else {
                        Log.w(TAG, "Non-IPv4 address: " + linkAddress);
                    }
                }
                if (gatewayAddressString != null) {
                    LinkAddress dest = null;
                    InetAddress gateway = NetworkUtils.numericToInetAddress(gatewayAddressString);
                    RouteInfo route = new RouteInfo(dest, gateway);
                    if (route.isIPv4Default()) {
                        staticIpConfiguration.gateway = gateway;
                    } else {
                        Log.w(TAG, "Non-IPv4 default route: " + route);
                    }
                }
                if (dnsServerAddressesString != null) {
                    for (String dnsServerAddressString : dnsServerAddressesString) {
                        InetAddress dnsServerAddress =
                                NetworkUtils.numericToInetAddress(dnsServerAddressString);
                        staticIpConfiguration.dnsServers.add(dnsServerAddress);
                    }
                }
                ipConfiguration.setStaticIpConfiguration(staticIpConfiguration);
                break;
            case DHCP:
            case UNASSIGNED:
                break;
            default:
                throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment);
        }

        // Process the proxy settings next
        if (proxySettingsString == null) {
            throw new XmlPullParserException("ProxySettings was missing in"
                    + " IpConfiguration section");
        }
        ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
        ipConfiguration.setProxySettings(proxySettings);
        switch (proxySettings) {
            case STATIC:
                if (proxyHost == null) {
                    throw new XmlPullParserException("ProxyHost was missing in"
                            + " IpConfiguration section");
                }
                if (proxyPort == -1) {
                    throw new XmlPullParserException("ProxyPort was missing in"
                            + " IpConfiguration section");
                }
                if (proxyExclusionList == null) {
                    throw new XmlPullParserException("ProxyExclusionList was missing in"
                            + " IpConfiguration section");
                }
                ipConfiguration.setHttpProxy(
                        new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
                break;
            case PAC:
                if (proxyPacFile == null) {
                    throw new XmlPullParserException("ProxyPac was missing in"
                            + " IpConfiguration section");
                }
                ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
                break;
            case NONE:
            case UNASSIGNED:
                break;
            default:
                throw new XmlPullParserException(
                        "Unknown proxy settings type: " + proxySettings);
        }

        return ipConfiguration;
    }

    /**
     * Returns a set of supported tags of <IpConfiguration> element for all minor versions of
     * this major version up to and including the specified minorVersion (only adding tags is
     * supported in minor versions, removal or changing the meaning of tags requires bumping
     * the major version and reseting the minor to 0).
     *
     * @param minorVersion  minor version number parsed from incoming data.
     */
    private static Set<String> getSupportedIpConfigurationTags(int minorVersion) {
        switch (minorVersion) {
            case 0:
            case 1:
                return IP_CONFIGURATION_MINOR_V0_V1_SUPPORTED_TAGS;
            default:
                Log.e(TAG, "Invalid minorVersion: " + minorVersion);
                return Collections.<String>emptySet();
        }
    }
}
