/*
 * Copyright 2014, 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.managedprovisioning;

import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_BT_MAC_ADDRESS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_BT_UUID;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_BT_DEVICE_ID;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_BT_USE_PROXY;
import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC;
import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC_V2;
import static java.nio.charset.StandardCharsets.UTF_8;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.text.TextUtils;

import com.android.managedprovisioning.Utils.IllegalProvisioningArgumentException;

import java.io.IOException;
import java.io.StringReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.IllformedLocaleException;
import java.util.Locale;
import java.util.Properties;

/**
 * This class can initialize a {@link ProvisioningParams} object from an intent.
 * A {@link ProvisioningParams} object stores various parameters for the device owner provisioning.
 * There are two kinds of intents that can be parsed it into {@link ProvisioningParams}:
 *
 * <p>
 * Intent was received via Nfc.
 * The intent contains the extra {@link NfcAdapter.EXTRA_NDEF_MESSAGES}, which indicates that
 * provisioning was started via Nfc bump. This extra contains an NDEF message, which contains an
 * NfcRecord with mime type {@link MIME_TYPE_PROVISIONING_NFC}. This record stores a serialized
 * properties object, which contains the serialized extra's described in the next option.
 * A typical use case would be a programmer application that sends an Nfc bump to start Nfc
 * provisioning from a programmer device.
 *
 * <p>
 * Intent was received directly.
 * The intent contains the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} or
 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} (which is deprecated and supported for
 * legacy reasons only), and may contain {@link #EXTRA_PROVISIONING_TIME_ZONE},
 * {@link #EXTRA_PROVISIONING_LOCAL_TIME}, {@link #EXTRA_PROVISIONING_LOCALE}, and
 * {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME}. A download
 * location for the device admin may be specified in
 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}, together with an optional
 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE}, an optional
 * http cookie header {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER}, and
 * the SHA-1 hash of the target file {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM} or
 * the SHA-1 hash of any certificate of the android package in the target file
 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM}. A download location for the device
 *  initializer may be specified in
 * {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}, together with an
 * optional (@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE}, an optional http
 * cookie header {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER} , and
 * the SHA-1 hash of the target file {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM}
 * or the SHA-1 hash of any certificate of the android package in the target file
 * {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM}.
 * Additional information to send through to the device initializer and admin may be specified in
 * {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}.
 * The optional boolean {@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED} indicates whether
 * system apps should not be disabled. The optional boolean
 * {@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION} specifies whether the device should be encrypted.
 * Furthermore a wifi network may be specified in {@link #EXTRA_PROVISIONING_WIFI_SSID}, and if
 * applicable {@link #EXTRA_PROVISIONING_WIFI_HIDDEN},
 * {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE}, {@link #EXTRA_PROVISIONING_WIFI_PASSWORD},
 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, {@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT},
 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}. The optional fields
 * {@link #EXTRA_PROVISIONING_BT_MAC_ADDRESS}, {@link #EXTRA_PROVISIONING_BT_UUID}, and
 * {@link #EXTRA_PROVISIONING_BT_DEVICE_ID} define how to connect to a remote device over Bluetooth.
 * The boolean {@link #EXTRA_PROVISIONING_BT_USE_PROXY}, if true, will allow this device to proxy
 * network activity over the defined Bluetooth connection during initial setup.
 * A typical use case would be the {@link BootReminder} sending the intent after device encryption
 * and reboot.
 *
 * <p>
 * If factory reset protection is enabled, the extra {@link
 * #EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} may hold data necessary to clear factory reset
 * protection challenges.
 *
 * <p>
 * Furthermore this class can construct the bundle of extras for the second kind of intent given a
 * {@link ProvisioningParams}, and it keeps track of the types of the extras in the
 * DEVICE_OWNER_x_EXTRAS, with x the appropriate type.
 */
public class MessageParser {
    private static final String EXTRA_PROVISIONING_STARTED_BY_NFC  =
            "com.android.managedprovisioning.extra.started_by_nfc";

    protected static final String[] DEVICE_OWNER_STRING_EXTRAS = {
        EXTRA_PROVISIONING_TIME_ZONE,
        EXTRA_PROVISIONING_LOCALE,
        EXTRA_PROVISIONING_WIFI_SSID,
        EXTRA_PROVISIONING_WIFI_SECURITY_TYPE,
        EXTRA_PROVISIONING_WIFI_PASSWORD,
        EXTRA_PROVISIONING_WIFI_PROXY_HOST,
        EXTRA_PROVISIONING_WIFI_PROXY_BYPASS,
        EXTRA_PROVISIONING_WIFI_PAC_URL,
        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
        EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM,
        EXTRA_PROVISIONING_BT_MAC_ADDRESS,
        EXTRA_PROVISIONING_BT_UUID,
        EXTRA_PROVISIONING_BT_DEVICE_ID
    };

    protected static final String[] DEVICE_OWNER_LONG_EXTRAS = {
        EXTRA_PROVISIONING_LOCAL_TIME
    };

    protected static final String[] DEVICE_OWNER_INT_EXTRAS = {
        EXTRA_PROVISIONING_WIFI_PROXY_PORT,
        EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE
    };

    protected static final String[] DEVICE_OWNER_BOOLEAN_EXTRAS = {
        EXTRA_PROVISIONING_WIFI_HIDDEN,
        EXTRA_PROVISIONING_STARTED_BY_NFC,
        EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
        EXTRA_PROVISIONING_SKIP_ENCRYPTION,
        EXTRA_PROVISIONING_BT_USE_PROXY
    };

    protected static final String[] DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
        EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,
        EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
    };

    protected static final String[] DEVICE_OWNER_COMPONENT_NAME_EXTRAS = {
        EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
        EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME
    };

    public void addProvisioningParamsToBundle(Bundle bundle, ProvisioningParams params) {
        bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, params.timeZone);
        bundle.putString(EXTRA_PROVISIONING_LOCALE, localeToString(params.locale));
        bundle.putString(EXTRA_PROVISIONING_WIFI_SSID, params.wifiInfo.ssid);
        bundle.putString(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, params.wifiInfo.securityType);
        bundle.putString(EXTRA_PROVISIONING_WIFI_PASSWORD, params.wifiInfo.password);
        bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_HOST, params.wifiInfo.proxyHost);
        bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS, params.wifiInfo.proxyBypassHosts);
        bundle.putString(EXTRA_PROVISIONING_WIFI_PAC_URL, params.wifiInfo.pacUrl);
        bundle.putInt(EXTRA_PROVISIONING_WIFI_PROXY_PORT, params.wifiInfo.proxyPort);
        bundle.putBoolean(EXTRA_PROVISIONING_WIFI_HIDDEN, params.wifiInfo.hidden);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
                params.deviceAdminPackageName);
        bundle.putParcelable(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
                params.deviceAdminComponentName);
        bundle.putInt(EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
                params.deviceAdminDownloadInfo.minVersion);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
                params.deviceAdminDownloadInfo.location);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
                params.deviceAdminDownloadInfo.cookieHeader);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
                Utils.byteArrayToString(params.deviceAdminDownloadInfo.packageChecksum));
        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM,
                Utils.byteArrayToString(params.deviceAdminDownloadInfo.certificateChecksum));
        bundle.putParcelable(EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME,
                params.deviceInitializerComponentName);
        bundle.putInt(EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE,
                params.deviceInitializerDownloadInfo.minVersion);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION,
                params.deviceInitializerDownloadInfo.location);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER,
                params.deviceInitializerDownloadInfo.cookieHeader);
        bundle.putString(EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM,
                Utils.byteArrayToString(params.deviceInitializerDownloadInfo.packageChecksum));
        bundle.putString(EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM,
                Utils.byteArrayToString(params.deviceInitializerDownloadInfo.certificateChecksum));

        bundle.putLong(EXTRA_PROVISIONING_LOCAL_TIME, params.localTime);
        bundle.putBoolean(EXTRA_PROVISIONING_STARTED_BY_NFC, params.startedByNfc);
        bundle.putBoolean(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
                params.leaveAllSystemAppsEnabled);
        bundle.putParcelable(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, params.adminExtrasBundle);
        bundle.putBoolean(EXTRA_PROVISIONING_SKIP_ENCRYPTION, params.skipEncryption);

        // Bluetooth parameters
        bundle.putString(EXTRA_PROVISIONING_BT_MAC_ADDRESS, params.bluetoothInfo.mac);
        bundle.putString(EXTRA_PROVISIONING_BT_UUID, params.bluetoothInfo.uuid);
        bundle.putString(EXTRA_PROVISIONING_BT_DEVICE_ID, params.bluetoothInfo.deviceIdentifier);
        bundle.putBoolean(EXTRA_PROVISIONING_BT_USE_PROXY, params.bluetoothInfo.useProxy);

        bundle.putParcelable(EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS,
                params.frpChallengeBundle);
    }

    public ProvisioningParams parseIntent(Intent intent)
            throws IllegalProvisioningArgumentException {
        ProvisionLogger.logi("Processing intent.");
        if (intent.hasExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
            return parseNfcIntent(intent);
        } else {
            return parseNonNfcIntent(intent);
        }
    }

    public ProvisioningParams parseNfcIntent(Intent nfcIntent)
            throws IllegalProvisioningArgumentException {
        ProvisionLogger.logi("Processing Nfc Payload.");
        // Only one first message with NFC_MIME_TYPE is used.
        for (Parcelable rawMsg : nfcIntent
                     .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
            NdefMessage msg = (NdefMessage) rawMsg;

            // Assume only first record of message is used.
            NdefRecord firstRecord = msg.getRecords()[0];
            String mimeType = new String(firstRecord.getType(), UTF_8);

            if (MIME_TYPE_PROVISIONING_NFC.equals(mimeType) ||
                    MIME_TYPE_PROVISIONING_NFC_V2.equals(mimeType)) {
                ProvisioningParams params = parseProperties(new String(firstRecord.getPayload()
                                , UTF_8));
                params.startedByNfc = true;
                return params;
            }
        }
        throw new IllegalProvisioningArgumentException(
                "Intent does not contain NfcRecord with the correct MIME type.");
    }

    // Note: EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE property contains a Properties object
    // serialized into String. See Properties.store() and Properties.load() for more details.
    // The property value is optional.
    private ProvisioningParams parseProperties(String data)
            throws IllegalProvisioningArgumentException {
        ProvisioningParams params = new ProvisioningParams();
        try {
            Properties props = new Properties();
            props.load(new StringReader(data));

            String s; // Used for parsing non-Strings.
            params.timeZone
                    = props.getProperty(EXTRA_PROVISIONING_TIME_ZONE);
            if ((s = props.getProperty(EXTRA_PROVISIONING_LOCALE)) != null) {
                params.locale = stringToLocale(s);
            }
            params.wifiInfo.ssid = props.getProperty(EXTRA_PROVISIONING_WIFI_SSID);
            params.wifiInfo.securityType = props.getProperty(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
            params.wifiInfo.password = props.getProperty(EXTRA_PROVISIONING_WIFI_PASSWORD);
            params.wifiInfo.proxyHost = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
            params.wifiInfo.proxyBypassHosts =
                    props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
            params.wifiInfo.pacUrl = props.getProperty(EXTRA_PROVISIONING_WIFI_PAC_URL);
            if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_PORT)) != null) {
                params.wifiInfo.proxyPort = Integer.parseInt(s);
            }
            if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_HIDDEN)) != null) {
                params.wifiInfo.hidden = Boolean.parseBoolean(s);
            }

            params.deviceAdminPackageName
                    = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
            String componentNameString = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
            if (componentNameString != null) {
                params.deviceAdminComponentName = ComponentName.unflattenFromString(
                        componentNameString);
            }
            if ((s = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE)) != null) {
                params.deviceAdminDownloadInfo.minVersion = Integer.parseInt(s);
            } else {
                params.deviceAdminDownloadInfo.minVersion =
                        ProvisioningParams.DEFAULT_MINIMUM_VERSION;
            }
            params.deviceAdminDownloadInfo.location
                    = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
            params.deviceAdminDownloadInfo.cookieHeader = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
            if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)) != null) {
                params.deviceAdminDownloadInfo.packageChecksum = Utils.stringToByteArray(s);
            }
            if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM))
                    != null) {
                params.deviceAdminDownloadInfo.certificateChecksum = Utils.stringToByteArray(s);
            }
            String name = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME);
            if (name != null) {
                params.deviceInitializerComponentName = ComponentName.unflattenFromString(name);
            }
            if ((s = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE)) != null) {
                params.deviceInitializerDownloadInfo.minVersion = Integer.parseInt(s);
            } else {
                params.deviceInitializerDownloadInfo.minVersion =
                        ProvisioningParams.DEFAULT_MINIMUM_VERSION;
            }
            params.deviceInitializerDownloadInfo.location = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION);
            params.deviceInitializerDownloadInfo.cookieHeader = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER);
            if ((s = props.getProperty(
                    EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM)) != null) {
                params.deviceInitializerDownloadInfo.packageChecksum = Utils.stringToByteArray(s);
            }
            if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM))
                    != null) {
                params.deviceInitializerDownloadInfo.certificateChecksum =
                        Utils.stringToByteArray(s);
            }

            if ((s = props.getProperty(EXTRA_PROVISIONING_LOCAL_TIME)) != null) {
                params.localTime = Long.parseLong(s);
            }

            if ((s = props.getProperty(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED)) != null) {
                params.leaveAllSystemAppsEnabled = Boolean.parseBoolean(s);
            }
            if ((s = props.getProperty(EXTRA_PROVISIONING_SKIP_ENCRYPTION)) != null) {
                params.skipEncryption = Boolean.parseBoolean(s);
            }

            params.bluetoothInfo.mac = props.getProperty(EXTRA_PROVISIONING_BT_MAC_ADDRESS);
            params.bluetoothInfo.uuid = props.getProperty(EXTRA_PROVISIONING_BT_UUID);
            params.bluetoothInfo.deviceIdentifier =
                    props.getProperty(EXTRA_PROVISIONING_BT_DEVICE_ID);
            if ((s = props.getProperty(EXTRA_PROVISIONING_BT_USE_PROXY)) != null) {
                params.bluetoothInfo.useProxy = Boolean.parseBoolean(s);
            }

            params.adminExtrasBundle = deserializeExtrasBundle(props,
                    EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);

            params.frpChallengeBundle = deserializeExtrasBundle(props,
                    EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS);

            checkValidityOfProvisioningParams(params);
            return params;
        } catch (IOException e) {
            throw new Utils.IllegalProvisioningArgumentException("Couldn't load payload", e);
        } catch (NumberFormatException e) {
            throw new Utils.IllegalProvisioningArgumentException("Incorrect numberformat.", e);
        } catch (IllformedLocaleException e) {
            throw new Utils.IllegalProvisioningArgumentException("Invalid locale.", e);
        }
    }

    /**
     * Get a {@link PersistableBundle} from a String property in a Properties object.
     * @param props the source of the extra
     * @param extraName key into the Properties object
     * @return the bundle or {@code null} if there was no property with the given name
     * @throws IOException if there was an error parsing the propery
     */
    private PersistableBundle deserializeExtrasBundle(Properties props, String extraName)
            throws IOException {
        PersistableBundle extrasBundle = null;
        String serializedExtras = props.getProperty(extraName);
        if (serializedExtras != null) {
            Properties extrasProp = new Properties();
            extrasProp.load(new StringReader(serializedExtras));
            extrasBundle = new PersistableBundle(extrasProp.size());
            for (String propName : extrasProp.stringPropertyNames()) {
                extrasBundle.putString(propName, extrasProp.getProperty(propName));
            }
        }
        return extrasBundle;
    }

    public ProvisioningParams parseNonNfcIntent(Intent intent)
            throws IllegalProvisioningArgumentException {
        ProvisionLogger.logi("Processing intent.");
        ProvisioningParams params = new ProvisioningParams();

        params.timeZone = intent.getStringExtra(EXTRA_PROVISIONING_TIME_ZONE);
        String localeString = intent.getStringExtra(EXTRA_PROVISIONING_LOCALE);
        if (localeString != null) {
            params.locale = stringToLocale(localeString);
        }
        params.wifiInfo.ssid = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID);
        params.wifiInfo.securityType = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
        params.wifiInfo.password = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PASSWORD);
        params.wifiInfo.proxyHost = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
        params.wifiInfo.proxyBypassHosts =
                intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
        params.wifiInfo.pacUrl = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PAC_URL);
        params.wifiInfo.proxyPort = intent.getIntExtra(EXTRA_PROVISIONING_WIFI_PROXY_PORT,
                ProvisioningParams.DEFAULT_WIFI_PROXY_PORT);
        params.wifiInfo.hidden = intent.getBooleanExtra(EXTRA_PROVISIONING_WIFI_HIDDEN,
                ProvisioningParams.DEFAULT_WIFI_HIDDEN);

        params.deviceAdminComponentName = (ComponentName) intent.getParcelableExtra(
                EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
        params.deviceAdminPackageName
                = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
        params.deviceAdminDownloadInfo.minVersion = intent.getIntExtra(
                EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
                ProvisioningParams.DEFAULT_MINIMUM_VERSION);
        params.deviceAdminDownloadInfo.location
                = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
        params.deviceAdminDownloadInfo.cookieHeader = intent.getStringExtra(
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
        String packageHash =
                intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
        if (packageHash != null) {
            params.deviceAdminDownloadInfo.packageChecksum = Utils.stringToByteArray(packageHash);
        }
        String certHash =
                intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_CERTIFICATE_CHECKSUM);
        if (certHash != null) {
            params.deviceAdminDownloadInfo.certificateChecksum = Utils.stringToByteArray(certHash);
        }
        params.deviceInitializerComponentName = (ComponentName) intent.getParcelableExtra(
                EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME);
        params.deviceInitializerDownloadInfo.minVersion = intent.getIntExtra(
                EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE,
                ProvisioningParams.DEFAULT_MINIMUM_VERSION);
        params.deviceInitializerDownloadInfo.location = intent.getStringExtra(
                EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION);
        params.deviceInitializerDownloadInfo.cookieHeader = intent.getStringExtra(
                EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER);
        packageHash = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM);
        if (packageHash != null) {
            params.deviceInitializerDownloadInfo.packageChecksum =
                    Utils.stringToByteArray(packageHash);
        }
        certHash =
                intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_INITIALIZER_CERTIFICATE_CHECKSUM);
        if (certHash != null) {
            params.deviceInitializerDownloadInfo.certificateChecksum =
                    Utils.stringToByteArray(certHash);
        }

        params.localTime = intent.getLongExtra(EXTRA_PROVISIONING_LOCAL_TIME,
                ProvisioningParams.DEFAULT_LOCAL_TIME);
        params.startedByNfc = intent.getBooleanExtra(EXTRA_PROVISIONING_STARTED_BY_NFC,
                false);
        params.leaveAllSystemAppsEnabled = intent.getBooleanExtra(
                EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
                ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED);
        params.skipEncryption = intent.getBooleanExtra(
                EXTRA_PROVISIONING_SKIP_ENCRYPTION,
                ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION);

        params.bluetoothInfo.mac = intent.getStringExtra(EXTRA_PROVISIONING_BT_MAC_ADDRESS);
        params.bluetoothInfo.uuid = intent.getStringExtra(EXTRA_PROVISIONING_BT_UUID);
        params.bluetoothInfo.deviceIdentifier =
                intent.getStringExtra(EXTRA_PROVISIONING_BT_DEVICE_ID);
        params.bluetoothInfo.useProxy =
                intent.getBooleanExtra(EXTRA_PROVISIONING_BT_USE_PROXY, false);

        try {
            params.adminExtrasBundle = (PersistableBundle) intent.getParcelableExtra(
                    EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
        } catch (ClassCastException e) {
            throw new IllegalProvisioningArgumentException("Extra "
                    + EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
                    + " must be of type PersistableBundle.", e);
        }

        try {
            params.frpChallengeBundle = intent.getParcelableExtra(
                    EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS);
        } catch (ClassCastException e) {
            throw new IllegalProvisioningArgumentException("Extra "
                    + EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
                    + " must be of type PersistableBundle.", e);
        }

        checkValidityOfProvisioningParams(params);
        return params;
    }

    /**
     * Check whether necessary fields are set.
     */
    private void checkValidityOfProvisioningParams(ProvisioningParams params)
            throws IllegalProvisioningArgumentException  {
        if (TextUtils.isEmpty(params.deviceAdminPackageName)
                && params.deviceAdminComponentName == null) {
            throw new IllegalProvisioningArgumentException("Must provide the name of the device"
                    + " admin package or component name");
        }
        checkDownloadInfoHasChecksum(params.deviceAdminDownloadInfo, "device admin");
        checkDownloadInfoHasChecksum(params.deviceInitializerDownloadInfo, "device initializer");
    }

    private void checkDownloadInfoHasChecksum(ProvisioningParams.PackageDownloadInfo info,
            String downloadName) throws IllegalProvisioningArgumentException {
        if (!TextUtils.isEmpty(info.location)) {
            if ((info.packageChecksum == null || info.packageChecksum.length == 0)
                    && (info.certificateChecksum == null || info.certificateChecksum.length == 0)) {
                throw new IllegalProvisioningArgumentException("Checksum of installer file"
                        + " or its certificate is required for downloading " + downloadName
                        + ", but neither is provided.");
            }
        }
    }

    public static Locale stringToLocale(String string)
        throws IllformedLocaleException {
        return new Locale.Builder().setLanguageTag(string.replace("_", "-")).build();
    }

    public static String localeToString(Locale locale) {
        if (locale != null) {
            return locale.getLanguage() + "_" + locale.getCountry();
        } else {
            return null;
        }
    }
}
