/*
 * Copyright 2016, 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.parser;

import static android.app.admin.DevicePolicyManager.ACTION_ESTABLISH_NETWORK_CONNECTION;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE;
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_COOKIE_HEADER;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMERS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMER_CONTENT;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMER_HEADER;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ORGANIZATION_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_PACKAGE_DOWNLOAD_COOKIE_HEADER;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_PACKAGE_DOWNLOAD_LOCATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_SIGNATURE_CHECKSUM;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SHOULD_LAUNCH_RESULT_INTENT;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SUPPORTED_MODES;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SUPPORT_URL;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_USE_MOBILE_DATA;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_DOMAIN;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_EAP_METHOD;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_IDENTITY;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PHASE2_AUTH;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
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_SECURITY_TYPE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE;
import static android.app.admin.DevicePolicyManager.FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED;
import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_CLOUD_ENROLLMENT;
import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_QR_CODE;
import static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED;

import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.managedprovisioning.common.Globals.ACTION_PROVISION_MANAGED_DEVICE_SILENTLY;
import static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS;
import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA;

import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.UserHandle;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
import com.android.managedprovisioning.common.ProvisionLogger;
import com.android.managedprovisioning.common.SettingsFacade;
import com.android.managedprovisioning.common.StoreUtils;
import com.android.managedprovisioning.common.Utils;
import com.android.managedprovisioning.model.DisclaimersParam;
import com.android.managedprovisioning.model.PackageDownloadInfo;
import com.android.managedprovisioning.model.ProvisioningParams;
import com.android.managedprovisioning.model.WifiInfo;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IllformedLocaleException;
import java.util.Map;
import java.util.Set;

/**
 * A parser which parses provisioning data from intent which stores in {@link Bundle} extras.
 */

@VisibleForTesting
public class ExtrasProvisioningDataParser implements ProvisioningDataParser {
    private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA =
            new HashSet<>(Arrays.asList(
                    ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE,
                    ACTION_PROVISION_FINANCED_DEVICE));

    private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA =
            new HashSet<>(Arrays.asList(
                    ACTION_PROVISION_MANAGED_DEVICE,
                    ACTION_PROVISION_MANAGED_PROFILE,
                    ACTION_PROVISION_MANAGED_DEVICE_SILENTLY));

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE_SHORT = "a.a.e.PAEB";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME_SHORT = "a.a.e.PDAPN";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME_SHORT = "a.a.e.PDACN";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE_SHORT = "a.a.e.PATM";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION_SHORT = "a.a.e.PKAOM";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED_SHORT = "a.a.e.PLASAE";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_TIME_ZONE_SHORT = "a.a.e.PTZ";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_LOCAL_TIME_SHORT = "a.a.e.PLT";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_LOCALE_SHORT = "a.a.e.PL";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_SSID_SHORT = "a.a.e.PWS";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_HIDDEN_SHORT = "a.a.e.PWH";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE_SHORT = "a.a.e.PWST";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PASSWORD_SHORT = "a.a.e.PWP";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_EAP_METHOD_SHORT = "a.a.e.PWEM";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PHASE2_AUTH_SHORT = "a.a.e.PWPA";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE_SHORT = "a.a.e.PWCC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE_SHORT = "a.a.e.PWUC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_IDENTITY_SHORT = "a.a.e.PWI";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY_SHORT = "a.a.e.PWAI";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_DOMAIN_SHORT = "a.a.e.PWD";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PROXY_HOST_SHORT = "a.a.e.PWPH";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PROXY_PORT_SHORT = "a.a.e.PWPRP";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS_SHORT = "a.a.e.PWPB";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_WIFI_PAC_URL_SHORT = "a.a.e.PWPU";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION_SHORT =
            "a.a.e.PDAPDL";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_ORGANIZATION_NAME_SHORT = "a.a.e.PON";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_SUPPORT_URL_SHORT = "a.a.e.PSU";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE_SHORT = "a.a.e.PDAMVC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER_SHORT =
            "a.a.e.PDAPDCH";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM_SHORT = "a.a.e.PDAPC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM_SHORT = "a.a.e.PDASC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION_SHORT = "a.a.e.PSE";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DISCLAIMERS_SHORT = "a.a.e.PD";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DISCLAIMER_HEADER_SHORT = "a.a.e.PDH";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_DISCLAIMER_CONTENT_SHORT = "a.a.e.PDC";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS_SHORT = "a.a.e.PSES";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_USE_MOBILE_DATA_SHORT = "a.a.e.PUMD";

    @VisibleForTesting
    static final String EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT_SHORT = "a.a.e.PPSGOO";

    private static final Map<String, String> SHORTER_EXTRAS = buildShorterExtrasMap();

    private static Map<String, String> buildShorterExtrasMap() {
        Map<String, String> shorterExtras = new HashMap<>();
        shorterExtras.put(
                EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,
                EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
                EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION,
                EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
                EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_TIME_ZONE, EXTRA_PROVISIONING_TIME_ZONE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_LOCAL_TIME, EXTRA_PROVISIONING_LOCAL_TIME_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_LOCALE, EXTRA_PROVISIONING_LOCALE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_SSID, EXTRA_PROVISIONING_WIFI_SSID_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_HIDDEN, EXTRA_PROVISIONING_WIFI_HIDDEN_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, EXTRA_PROVISIONING_WIFI_SECURITY_TYPE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PASSWORD, EXTRA_PROVISIONING_WIFI_PASSWORD_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_EAP_METHOD, EXTRA_PROVISIONING_WIFI_EAP_METHOD_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PHASE2_AUTH, EXTRA_PROVISIONING_WIFI_PHASE2_AUTH_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE,
                EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE,
                EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_IDENTITY, EXTRA_PROVISIONING_WIFI_IDENTITY_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY,
                EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_DOMAIN, EXTRA_PROVISIONING_WIFI_DOMAIN_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PROXY_HOST, EXTRA_PROVISIONING_WIFI_PROXY_HOST_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PROXY_PORT, EXTRA_PROVISIONING_WIFI_PROXY_PORT_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PROXY_BYPASS, EXTRA_PROVISIONING_WIFI_PROXY_BYPASS_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_WIFI_PAC_URL, EXTRA_PROVISIONING_WIFI_PAC_URL_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_ORGANIZATION_NAME, EXTRA_PROVISIONING_ORGANIZATION_NAME_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_SUPPORT_URL, EXTRA_PROVISIONING_SUPPORT_URL_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
                EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM,
                EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_SKIP_ENCRYPTION, EXTRA_PROVISIONING_SKIP_ENCRYPTION_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DISCLAIMERS, EXTRA_PROVISIONING_DISCLAIMERS_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DISCLAIMER_HEADER, EXTRA_PROVISIONING_DISCLAIMER_HEADER_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_DISCLAIMER_CONTENT, EXTRA_PROVISIONING_DISCLAIMER_CONTENT_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS,
                EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS_SHORT);
        shorterExtras.put(
                EXTRA_PROVISIONING_USE_MOBILE_DATA, EXTRA_PROVISIONING_USE_MOBILE_DATA_SHORT);
        shorterExtras.put(EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT,
                EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT_SHORT);
        return shorterExtras;
    }

    private final Utils mUtils;
    private final ParserUtils mParserUtils;
    private final SettingsFacade mSettingsFacade;
    private final Context mContext;
    private final ManagedProvisioningSharedPreferences mSharedPreferences;

    ExtrasProvisioningDataParser(Context context, Utils utils, ParserUtils parserUtils,
            SettingsFacade settingsFacade) {
        this(context, utils, parserUtils, settingsFacade,
                new ManagedProvisioningSharedPreferences(context));
    }

    @VisibleForTesting
    ExtrasProvisioningDataParser(Context context, Utils utils, ParserUtils parserUtils,
            SettingsFacade settingsFacade, ManagedProvisioningSharedPreferences sharedPreferences) {
        mContext = checkNotNull(context);
        mUtils = checkNotNull(utils);
        mParserUtils = checkNotNull(parserUtils);
        mSettingsFacade = checkNotNull(settingsFacade);
        mSharedPreferences = checkNotNull(sharedPreferences);
    }

    @Override
    public ProvisioningParams parse(Intent provisioningIntent)
            throws IllegalProvisioningArgumentException{
        String provisioningAction = provisioningIntent.getAction();
        if (ACTION_RESUME_PROVISIONING.equals(provisioningAction)) {
            return getParcelableExtraFromLongName(provisioningIntent,
                    ProvisioningParams.EXTRA_PROVISIONING_PARAMS);
        }
        if (PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA.contains(provisioningAction)) {
            ProvisionLogger.logi("Processing mininalist extras intent.");
            return parseMinimalistSupportedProvisioningDataInternal(provisioningIntent, mContext)
                    .build();
        } else if (PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA.contains(
                provisioningAction)) {
            return parseAllSupportedProvisioningData(provisioningIntent, mContext);
        } else if (ACTION_ESTABLISH_NETWORK_CONNECTION.equals(provisioningAction)) {
            return parseNetworkProvisioningData(provisioningIntent);
        } else {
            throw new IllegalProvisioningArgumentException("Unsupported provisioning action: "
                    + provisioningAction);
        }
    }

    /**
     * Returns a short version of the requested extra.
     */
    static String getShortExtraNames(String extraName) {
        return SHORTER_EXTRAS.get(extraName);
    }

    private boolean hasExtraFromLongName(Intent intent, String longName) {
        return intent.hasExtra(longName) || intent.hasExtra(getShortExtraNames(longName));
    }

    @Nullable
    private <T extends Parcelable> T getParcelableExtraFromLongName(
            Intent intent, String longName) {
        if (intent.hasExtra(longName)) {
            return intent.getParcelableExtra(longName);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.hasExtra(shortName)) {
            return intent.getParcelableExtra(shortName);
        }
        return null;
    }

    @Nullable
    private Parcelable[] getParcelableArrayExtraFromLongName(Intent intent, String longName) {
        if (intent.hasExtra(longName)) {
            return intent.getParcelableArrayExtra(longName);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.hasExtra(shortName)) {
            return intent.getParcelableArrayExtra(shortName);
        }
        return null;
    }

    private int getIntExtraFromLongName(Intent intent, String longName, int defaultValue) {
        if (intent.hasExtra(longName)) {
            return intent.getIntExtra(longName, defaultValue);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.hasExtra(shortName)) {
            return intent.getIntExtra(shortName, defaultValue);
        }
        return defaultValue;
    }

    private boolean getBooleanExtraFromLongName(
            Intent intent, String longName, boolean defaultValue) {
        if (intent.hasExtra(longName)) {
            return intent.getBooleanExtra(longName, defaultValue);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.hasExtra(shortName)) {
            return intent.getBooleanExtra(shortName, defaultValue);
        }
        return defaultValue;
    }

    private long getParcelableExtraFromLongName(Intent intent, String longName, long defaultValue) {
        if (intent.hasExtra(longName)) {
            return intent.getLongExtra(longName, defaultValue);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.hasExtra(shortName)) {
            return intent.getLongExtra(shortName, defaultValue);
        }
        return defaultValue;
    }

    @Nullable
    private String getStringExtraFromLongName(Intent intent, String longName) {
        if (intent.getStringExtra(longName) != null) {
            return intent.getStringExtra(longName);
        }
        String shortName = getShortExtraNames(longName);
        if (intent.getStringExtra(shortName) != null) {
            return intent.getStringExtra(shortName);
        }
        return null;
    }

    /**
     * Parses minimal supported set of parameters from bundle extras of a provisioning intent.
     *
     * <p>Here is the list of supported parameters.
     * <ul>
     *     <li>{@link EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
     *     <li>
     *         {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} only in
     *         {@link ACTION_PROVISION_MANAGED_PROFILE}.
     *     </li>
     *     <li>{@link EXTRA_PROVISIONING_SKIP_ENCRYPTION}</li>
     *     <li>{@link EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}</li>
     *     <li>{@link EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}</li>
     *     <li>{@link EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</li>
     * </ul>
     */
    private ProvisioningParams.Builder parseMinimalistSupportedProvisioningDataInternal(
            Intent intent, Context context)
            throws IllegalProvisioningArgumentException {
        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
        boolean isProvisionManagedDeviceFromTrustedSourceIntent =
                ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(intent.getAction());
        boolean isFinancedDeviceProvisioning =
                ACTION_PROVISION_FINANCED_DEVICE.equals(intent.getAction());
        final boolean isManagedProfileAction =
                ACTION_PROVISION_MANAGED_PROFILE.equals(intent.getAction());
        try {
            final long provisioningId = mSharedPreferences.incrementAndGetProvisioningId();
            String provisioningAction = mParserUtils.extractProvisioningAction(
                    intent, mSettingsFacade, mContext);

            // Parse device admin package name and component name.
            ComponentName deviceAdminComponentName = getParcelableExtraFromLongName(
                    intent, EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
            // Device admin package name is deprecated. It is only supported in Profile Owner
            // provisioning and when resuming NFC provisioning.
            String deviceAdminPackageName = null;
            if (isManagedProfileAction) {
                // In L, we only support package name. This means some DPC may still send us the
                // device admin package name only. Attempts to obtain the package name from extras.
                deviceAdminPackageName = getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
                // For profile owner, the device admin package should be installed. Verify the
                // device admin package.
                deviceAdminComponentName = mUtils.findDeviceAdmin(
                        deviceAdminPackageName,
                        deviceAdminComponentName,
                        context,
                        UserHandle.myUserId());
                // Since the device admin package must be installed at this point and its component
                // name has been obtained, it should be safe to set the deprecated package name
                // value to null.
                deviceAdminPackageName = null;
            }

            final boolean skipEducationScreens = shouldSkipEducationScreens(intent);

            // Only when provisioning PO with ACTION_PROVISION_MANAGED_PROFILE
            final boolean keepAccountMigrated = isManagedProfileAction
                            && getBooleanExtraFromLongName(
                                intent, EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION,
                                ProvisioningParams
                                        .DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED);

            DisclaimersParam disclaimersParam = new DisclaimersParserImpl(context, provisioningId)
                    .parse(getParcelableArrayExtraFromLongName(
                            intent, EXTRA_PROVISIONING_DISCLAIMERS));

            String organizationName =
                    getStringExtraFromLongName(intent, EXTRA_PROVISIONING_ORGANIZATION_NAME);
            String supportUrl = null;
            if (isProvisionManagedDeviceFromTrustedSourceIntent || isFinancedDeviceProvisioning) {
                supportUrl = getStringExtraFromLongName(intent, EXTRA_PROVISIONING_SUPPORT_URL);
            }

            final boolean leaveAllSystemAppsEnabled = isManagedProfileAction
                    ? false
                    : (isFinancedDeviceProvisioning ||
                            getBooleanExtraFromLongName(
                                    intent, EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
                                    ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED));

            int provisioningTrigger = mParserUtils.extractProvisioningTrigger(intent);
            int initiatorRequestedProvisioningModes =
                    getInitiatorRequestedProvisioningModes(intent);

            final boolean adminOptedOutOfSensorsPermissionGrants =
                    getBooleanExtraFromLongName(intent,
                            EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT,
                            ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT);
            return ProvisioningParams.Builder.builder()
                    .setProvisioningId(provisioningId)
                    .setProvisioningAction(provisioningAction)
                    .setDeviceAdminComponentName(deviceAdminComponentName)
                    .setDeviceAdminPackageName(deviceAdminPackageName)
                    .setSkipEncryption(
                            getBooleanExtraFromLongName(
                                    intent, EXTRA_PROVISIONING_SKIP_ENCRYPTION,
                                    ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION))
                    .setLeaveAllSystemAppsEnabled(leaveAllSystemAppsEnabled)
                    .setAdminExtrasBundle(getParcelableExtraFromLongName(
                            intent, EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE))
                    .setDisclaimersParam(disclaimersParam)
                    .setKeepAccountMigrated(keepAccountMigrated)
                    .setSkipEducationScreens(skipEducationScreens)
                    .setAccountToMigrate(getParcelableExtraFromLongName(
                            intent, EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE))
                    .setOrganizationName(organizationName)
                    .setSupportUrl(supportUrl)
                    .setIsQrProvisioning(provisioningTrigger == PROVISIONING_TRIGGER_QR_CODE)
                    .setProvisioningTrigger(provisioningTrigger)
                    .setAllowedProvisioningModes(mParserUtils.getAllowedProvisioningModes(
                            mContext, initiatorRequestedProvisioningModes, mUtils))
                    .setInitiatorRequestedProvisioningModes(
                            initiatorRequestedProvisioningModes)
                    .setSkipOwnershipDisclaimer(getSkipOwnershipDisclaimer(intent))
                    .setReturnBeforePolicyCompliance(getReturnBeforePolicyCompliance(intent))
                    .setDeviceOwnerPermissionGrantOptOut(
                            adminOptedOutOfSensorsPermissionGrants)
                    .setAllowOffline(getBooleanExtraFromLongName(
                            intent,
                            EXTRA_PROVISIONING_ALLOW_OFFLINE,
                            ProvisioningParams.DEFAULT_EXTRA_ALLOW_OFFLINE))
                    .setRoleHolderDownloadInfo(parseRoleHolderDownloadInfoFromExtras(intent))
                    .setProvisioningShouldLaunchResultIntent(
                            getProvisioningShouldLaunchResultIntent(intent));
        } catch (ClassCastException e) {
            throw new IllegalProvisioningArgumentException("Extra has invalid type", e);
        } catch (IllegalArgumentException e) {
            throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
        } catch (NullPointerException e) {
            throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
        }
    }

    private boolean getProvisioningShouldLaunchResultIntent(Intent intent) {
        if (!intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)
                && !intent.getAction().equals(ACTION_PROVISION_MANAGED_PROFILE)) {
            return ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SHOULD_LAUNCH_RESULT_INTENT;
        }
        return getBooleanExtraFromLongName(
                intent,
                EXTRA_PROVISIONING_SHOULD_LAUNCH_RESULT_INTENT,
                ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SHOULD_LAUNCH_RESULT_INTENT);
    }

    private boolean getSkipOwnershipDisclaimer(Intent intent) {
        if (!intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)) {
            return ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_OWNERSHIP_DISCLAIMER;
        }
        return getBooleanExtraFromLongName(
                intent,
                DevicePolicyManager.EXTRA_PROVISIONING_SKIP_OWNERSHIP_DISCLAIMER,
                ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_OWNERSHIP_DISCLAIMER);
    }

    private boolean getReturnBeforePolicyCompliance(Intent intent) {
        if (intent.getAction().equals(ACTION_PROVISION_MANAGED_PROFILE)) {
            // TODO(b/182462297): Default to false after in-setup wizard is no longer supported
            return mSettingsFacade.isDuringSetupWizard(mContext);
        }
        // TODO(b/177849035): Remove financed device-specific logic
        if (intent.getAction().equals(ACTION_PROVISION_FINANCED_DEVICE)) {
            return true;
        }
        return getBooleanExtraFromLongName(
                intent,
                EXTRA_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE,
                /* defaultValue */ true);
    }

    private int getInitiatorRequestedProvisioningModes(Intent intent) {
        if (!intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)) {
            return ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES;
        }
        int supportedModes = getIntExtraFromLongName(intent,
                EXTRA_PROVISIONING_SUPPORTED_MODES,
                FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED);
        mParserUtils.validateSupportedModes(supportedModes);
        return supportedModes;
    }

    /**
     * When {@link DevicePolicyManager#EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS} is passed as
     * a provisioning extra, we only process it for managed Google account enrollment and
     * persistent device owner.
     */
    private boolean shouldSkipEducationScreens(Intent intent) {
        if (!getBooleanExtraFromLongName(intent,
                EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS,
                DEFAULT_EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS)) {
            return false;
        }
        // TODO(b/175021111): Remove managed account provisioning-specific logic in MP for the
        // skip education screens extra.
        int provisioningTrigger = mParserUtils.extractProvisioningTrigger(intent);
        if (provisioningTrigger == PROVISIONING_TRIGGER_QR_CODE
                || provisioningTrigger == PROVISIONING_TRIGGER_CLOUD_ENROLLMENT
                || ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
            return false;
        }
        return isFullyManagedDeviceAction(intent);
    }

    private boolean isFullyManagedDeviceAction(Intent intent) {
        return ACTION_PROVISION_MANAGED_DEVICE.equals(intent.getAction())
                || ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(intent.getAction());
    }

    /**
     * Parses an intent and return a corresponding {@link ProvisioningParams} object.
     *
     * @param intent intent to be parsed.
     * @param context a context
     */
    private ProvisioningParams parseAllSupportedProvisioningData(Intent intent, Context context)
            throws IllegalProvisioningArgumentException {
        try {
            ProvisionLogger.logi("Processing all supported extras intent: " + intent.getAction());
            return parseMinimalistSupportedProvisioningDataInternal(intent, context)
                    // Parse time zone, local time and locale.
                    .setTimeZone(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_TIME_ZONE))
                    .setLocalTime(
                            getParcelableExtraFromLongName(
                                    intent, EXTRA_PROVISIONING_LOCAL_TIME,
                                    ProvisioningParams.DEFAULT_LOCAL_TIME))
                    .setLocale(StoreUtils.stringToLocale(
                            getStringExtraFromLongName(intent,EXTRA_PROVISIONING_LOCALE)))
                    .setUseMobileData(
                            getBooleanExtraFromLongName(
                                    intent, EXTRA_PROVISIONING_USE_MOBILE_DATA,
                                    DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA))
                    // Parse WiFi configuration.
                    .setWifiInfo(parseWifiInfoFromExtras(intent))
                    // Parse device admin package download info.
                    .setDeviceAdminDownloadInfo(parsePackageDownloadInfoFromExtras(intent))
                    // Cases where startedByTrustedSource can be true are
                    // 1. We are reloading a stored provisioning intent, either Nfc bump or
                    //    PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE, after encryption reboot,
                    //    which is a self-originated intent.
                    // 2. the intent is from a trusted source, for example QR provisioning.
                    .setStartedByTrustedSource(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE
                            .equals(intent.getAction()))
                    .build();
        }  catch (IllegalArgumentException e) {
            throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
        }  catch (IllformedLocaleException e) {
            throw new IllegalProvisioningArgumentException("Invalid locale format!", e);
        }  catch (NullPointerException e) {
            throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
        }
    }

    /**
     * Parses an intent and return a corresponding {@link ProvisioningParams} object.
     *
     * @param intent intent to be parsed.
     */
    private ProvisioningParams parseNetworkProvisioningData(Intent intent)
            throws IllegalProvisioningArgumentException {
        try {
            ProvisionLogger.logi("Processing network-related extras intent: " + intent.getAction());
            return ProvisioningParams.Builder.builder(/* skipValidation= */ true)
                    .setUseMobileData(
                            getBooleanExtraFromLongName(
                                    intent, EXTRA_PROVISIONING_USE_MOBILE_DATA,
                                    DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA))
                    .setWifiInfo(parseWifiInfoFromExtras(intent))
                    .build();
        }  catch (IllegalArgumentException e) {
            throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
        }  catch (IllformedLocaleException e) {
            throw new IllegalProvisioningArgumentException("Invalid locale format!", e);
        }  catch (NullPointerException e) {
            throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
        }
    }

    /**
     * Parses Wifi configuration from an Intent and returns the result in {@link WifiInfo}.
     */
    @Nullable
    private WifiInfo parseWifiInfoFromExtras(Intent intent) {
        if (getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_SSID) == null) {
            return null;
        }
        return WifiInfo.Builder.builder()
                .setSsid(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_SSID))
                .setSecurityType(
                        getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_SECURITY_TYPE))
                .setPassword(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_PASSWORD))
                .setProxyHost(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_PROXY_HOST))
                .setProxyBypassHosts(
                        getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_PROXY_BYPASS))
                .setPacUrl(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_PAC_URL))
                .setProxyPort(getIntExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_PROXY_PORT,
                        WifiInfo.DEFAULT_WIFI_PROXY_PORT))
                .setEapMethod(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_EAP_METHOD))
                .setPhase2Auth(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_PHASE2_AUTH))
                .setCaCertificate(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE))
                .setUserCertificate(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE))
                .setIdentity(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_IDENTITY))
                .setAnonymousIdentity(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY))
                .setDomain(getStringExtraFromLongName(intent, EXTRA_PROVISIONING_WIFI_DOMAIN))
                .setHidden(getBooleanExtraFromLongName(
                        intent, EXTRA_PROVISIONING_WIFI_HIDDEN, WifiInfo.DEFAULT_WIFI_HIDDEN))
                .build();
    }

    /**
     * Parses device admin package download info configuration from an Intent and returns the result
     * in {@link PackageDownloadInfo}.
     */
    @Nullable
    private PackageDownloadInfo parsePackageDownloadInfoFromExtras(Intent intent) {
        if (getStringExtraFromLongName(
                intent, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION) == null) {
            return null;
        }
        PackageDownloadInfo.Builder downloadInfoBuilder = PackageDownloadInfo.Builder.builder()
                .setMinVersion(getIntExtraFromLongName(
                        intent, EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
                        PackageDownloadInfo.DEFAULT_MINIMUM_VERSION))
                .setLocation(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION))
                .setCookieHeader(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER));
        String packageHash =
                getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
        if (packageHash != null) {
            downloadInfoBuilder.setPackageChecksum(StoreUtils.stringToByteArray(packageHash));
        }
        String sigHash = getStringExtraFromLongName(
                intent, EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM);
        if (sigHash != null) {
            downloadInfoBuilder.setSignatureChecksum(StoreUtils.stringToByteArray(sigHash));
        }
        return downloadInfoBuilder.build();
    }

    /**
     * Parses role holder package download info configuration from an Intent and returns the result
     * in {@link PackageDownloadInfo}.
     *
     * @return the {@link PackageDownloadInfo} or {@code null} if not supplied alongside {@link
     * DevicePolicyManager#ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}, {@link
     * DevicePolicyManager#EXTRA_PROVISIONING_ROLE_HOLDER_PACKAGE_DOWNLOAD_LOCATION} or
     * {@link DevicePolicyManager#EXTRA_PROVISIONING_ROLE_HOLDER_SIGNATURE_CHECKSUM}.
     */
    @Nullable
    private PackageDownloadInfo parseRoleHolderDownloadInfoFromExtras(Intent intent) {
        if (!intent.getAction().equals(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE)) {
            ProvisionLogger.logi("Cannot parse role holder download info for non-trusted source "
                    + "provisioning.");
            return null;
        }
        String downloadLocation = getStringExtraFromLongName(
                intent, EXTRA_PROVISIONING_ROLE_HOLDER_PACKAGE_DOWNLOAD_LOCATION);
        if (downloadLocation == null) {
            ProvisionLogger.logi("Cannot parse role holder download info, because it does not "
                    + "include the download location extra.");
            return null;
        }
        String sigHash = getStringExtraFromLongName(
                intent, EXTRA_PROVISIONING_ROLE_HOLDER_SIGNATURE_CHECKSUM);
        if (sigHash == null) {
            ProvisionLogger.logi("Cannot parse role holder download info, because it does not "
                    + "include the signature checksum extra.");
            return null;
        }
        PackageDownloadInfo.Builder downloadInfoBuilder = PackageDownloadInfo.Builder.builder()
                .setLocation(downloadLocation)
                .setCookieHeader(getStringExtraFromLongName(
                        intent, EXTRA_PROVISIONING_ROLE_HOLDER_PACKAGE_DOWNLOAD_COOKIE_HEADER));
        downloadInfoBuilder.setSignatureChecksum(StoreUtils.stringToByteArray(sigHash));
        return downloadInfoBuilder.build();
    }
}