Home | History | Annotate | Download | only in parser
      1 /*
      2  * Copyright 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.managedprovisioning.parser;
     18 
     19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
     20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
     21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
     22 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE;
     23 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
     24 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
     25 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
     26 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
     27 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE;
     28 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
     29 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER;
     30 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
     31 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI;
     32 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL;
     33 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
     34 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM;
     35 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMERS;
     36 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION;
     37 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
     38 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
     39 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
     40 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI;
     41 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR;
     42 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ORGANIZATION_NAME;
     43 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
     44 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_CONSENT;
     45 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_SETUP;
     46 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SUPPORT_URL;
     47 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
     48 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_USE_MOBILE_DATA;
     49 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
     50 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
     51 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
     52 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
     53 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST;
     54 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT;
     55 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
     56 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
     57 import static com.android.internal.util.Preconditions.checkNotNull;
     58 import static com.android.managedprovisioning.common.Globals.ACTION_PROVISION_MANAGED_DEVICE_SILENTLY;
     59 import static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
     60 import static com.android.managedprovisioning.model.ProvisioningParams
     61         .DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA;
     62 import static com.android.managedprovisioning.model.ProvisioningParams.inferStaticDeviceAdminPackageName;
     63 
     64 import android.app.admin.DevicePolicyManager;
     65 import android.content.ComponentName;
     66 import android.content.Context;
     67 import android.content.Intent;
     68 import android.net.Uri;
     69 import android.os.Bundle;
     70 import android.os.PersistableBundle;
     71 import android.os.UserHandle;
     72 import android.support.annotation.Nullable;
     73 import android.support.annotation.VisibleForTesting;
     74 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
     75 import com.android.managedprovisioning.common.LogoUtils;
     76 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
     77 import com.android.managedprovisioning.common.ProvisionLogger;
     78 import com.android.managedprovisioning.common.StoreUtils;
     79 import com.android.managedprovisioning.common.Utils;
     80 import com.android.managedprovisioning.model.DisclaimersParam;
     81 import com.android.managedprovisioning.model.PackageDownloadInfo;
     82 import com.android.managedprovisioning.model.ProvisioningParams;
     83 import com.android.managedprovisioning.model.WifiInfo;
     84 import java.util.Arrays;
     85 import java.util.Collections;
     86 import java.util.HashSet;
     87 import java.util.IllformedLocaleException;
     88 import java.util.Set;
     89 
     90 /**
     91  * A parser which parses provisioning data from intent which stores in {@link Bundle} extras.
     92  */
     93 
     94 @VisibleForTesting
     95 public class ExtrasProvisioningDataParser implements ProvisioningDataParser {
     96     private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA =
     97             new HashSet<>(Collections.singletonList(
     98                     ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE));
     99 
    100     private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA =
    101             new HashSet<>(Arrays.asList(
    102                     ACTION_PROVISION_MANAGED_DEVICE,
    103                     ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
    104                     ACTION_PROVISION_MANAGED_USER,
    105                     ACTION_PROVISION_MANAGED_PROFILE,
    106                     ACTION_PROVISION_MANAGED_DEVICE_SILENTLY));
    107 
    108     private final Utils mUtils;
    109     private final Context mContext;
    110     private final ManagedProvisioningSharedPreferences mSharedPreferences;
    111 
    112     ExtrasProvisioningDataParser(Context context, Utils utils) {
    113         this(context, utils, new ManagedProvisioningSharedPreferences(context));
    114     }
    115 
    116     @VisibleForTesting
    117     ExtrasProvisioningDataParser(Context context, Utils utils,
    118             ManagedProvisioningSharedPreferences sharedPreferences) {
    119         mContext = checkNotNull(context);
    120         mUtils = checkNotNull(utils);
    121         mSharedPreferences = checkNotNull(sharedPreferences);
    122     }
    123 
    124     @Override
    125     public ProvisioningParams parse(Intent provisioningIntent)
    126             throws IllegalProvisioningArgumentException{
    127         String provisioningAction = provisioningIntent.getAction();
    128         if (ACTION_RESUME_PROVISIONING.equals(provisioningAction)) {
    129             return provisioningIntent.getParcelableExtra(
    130                     ProvisioningParams.EXTRA_PROVISIONING_PARAMS);
    131         }
    132         if (PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA.contains(provisioningAction)) {
    133             ProvisionLogger.logi("Processing mininalist extras intent.");
    134             return parseMinimalistSupportedProvisioningDataInternal(provisioningIntent, mContext)
    135                     .build();
    136         } else if (PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA.contains(
    137                 provisioningAction)) {
    138             return parseAllSupportedProvisioningData(provisioningIntent, mContext);
    139         } else {
    140             throw new IllegalProvisioningArgumentException("Unsupported provisioning action: "
    141                     + provisioningAction);
    142         }
    143     }
    144 
    145     /**
    146      * Parses minimal supported set of parameters from bundle extras of a provisioning intent.
    147      *
    148      * <p>Here is the list of supported parameters.
    149      * <ul>
    150      *     <li>{@link EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
    151      *     <li>
    152      *         {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} only in
    153      *         {@link ACTION_PROVISION_MANAGED_PROFILE}.
    154      *     </li>
    155      *     <li>{@link EXTRA_PROVISIONING_LOGO_URI}</li>
    156      *     <li>{@link EXTRA_PROVISIONING_MAIN_COLOR}</li>
    157      *     <li>
    158      *         {@link EXTRA_PROVISIONING_SKIP_USER_SETUP} only in
    159      *         {@link ACTION_PROVISION_MANAGED_USER} and {@link ACTION_PROVISION_MANAGED_DEVICE}.
    160      *     </li>
    161      *     <li>{@link EXTRA_PROVISIONING_SKIP_ENCRYPTION}</li>
    162      *     <li>{@link EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}</li>
    163      *     <li>{@link EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}</li>
    164      *     <li>{@link EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</li>
    165      *     <li>{@link EXTRA_PROVISIONING_SKIP_USER_CONSENT}</li>
    166      * </ul>
    167      */
    168     private ProvisioningParams.Builder parseMinimalistSupportedProvisioningDataInternal(
    169             Intent intent, Context context)
    170             throws IllegalProvisioningArgumentException {
    171         final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
    172         boolean isProvisionManagedDeviceFromTrustedSourceIntent =
    173                 ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(intent.getAction());
    174         try {
    175             final long provisioningId = mSharedPreferences.incrementAndGetProvisioningId();
    176             String provisioningAction = mUtils.mapIntentToDpmAction(intent);
    177             final boolean isManagedProfileAction =
    178                     ACTION_PROVISION_MANAGED_PROFILE.equals(provisioningAction);
    179 
    180             // Parse device admin package name and component name.
    181             ComponentName deviceAdminComponentName = (ComponentName) intent.getParcelableExtra(
    182                     EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
    183             // Device admin package name is deprecated. It is only supported in Profile Owner
    184             // provisioning and when resuming NFC provisioning.
    185             String deviceAdminPackageName = null;
    186             if (isManagedProfileAction) {
    187                 // In L, we only support package name. This means some DPC may still send us the
    188                 // device admin package name only. Attempts to obtain the package name from extras.
    189                 deviceAdminPackageName = intent.getStringExtra(
    190                         EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
    191                 // For profile owner, the device admin package should be installed. Verify the
    192                 // device admin package.
    193                 deviceAdminComponentName = mUtils.findDeviceAdmin(
    194                         deviceAdminPackageName,
    195                         deviceAdminComponentName,
    196                         context,
    197                         UserHandle.myUserId());
    198                 // Since the device admin package must be installed at this point and its component
    199                 // name has been obtained, it should be safe to set the deprecated package name
    200                 // value to null.
    201                 deviceAdminPackageName = null;
    202             }
    203 
    204             // Parse skip user setup in ACTION_PROVISION_MANAGED_USER and
    205             // ACTION_PROVISION_MANAGED_DEVICE (sync auth) only. This extra is not supported if
    206             // provisioning was started by trusted source, as it is not clear where SUW should
    207             // continue from.
    208             boolean skipUserSetup = ProvisioningParams.DEFAULT_SKIP_USER_SETUP;
    209             if (!isProvisionManagedDeviceFromTrustedSourceIntent
    210                     && (provisioningAction.equals(ACTION_PROVISION_MANAGED_USER)
    211                             || provisioningAction.equals(ACTION_PROVISION_MANAGED_DEVICE))) {
    212                 skipUserSetup = intent.getBooleanExtra(EXTRA_PROVISIONING_SKIP_USER_SETUP,
    213                         ProvisioningParams.DEFAULT_SKIP_USER_SETUP);
    214             }
    215 
    216             // Only current DeviceOwner can specify EXTRA_PROVISIONING_SKIP_USER_CONSENT when
    217             // provisioning PO with ACTION_PROVISION_MANAGED_PROFILE
    218             final boolean skipUserConsent = isManagedProfileAction
    219                             && intent.getBooleanExtra(EXTRA_PROVISIONING_SKIP_USER_CONSENT,
    220                                     ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_USER_CONSENT)
    221                             && mUtils.isPackageDeviceOwner(dpm, inferStaticDeviceAdminPackageName(
    222                                     deviceAdminComponentName, deviceAdminPackageName));
    223 
    224             // Only when provisioning PO with ACTION_PROVISION_MANAGED_PROFILE
    225             final boolean keepAccountMigrated = isManagedProfileAction
    226                             && intent.getBooleanExtra(EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION,
    227                             ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED);
    228 
    229             // Parse main color and organization's logo. This is not supported in managed device
    230             // from trusted source provisioning because, currently, there is no way to send
    231             // organization logo to the device at this stage.
    232             Integer mainColor = ProvisioningParams.DEFAULT_MAIN_COLOR;
    233             if (!isProvisionManagedDeviceFromTrustedSourceIntent) {
    234                 if (intent.hasExtra(EXTRA_PROVISIONING_MAIN_COLOR)) {
    235                     mainColor = intent.getIntExtra(EXTRA_PROVISIONING_MAIN_COLOR, 0 /* not used */);
    236                 }
    237                 parseOrganizationLogoUrlFromExtras(context, intent);
    238             }
    239 
    240             DisclaimersParam disclaimersParam = new DisclaimersParser(context, provisioningId)
    241                     .parse(intent.getParcelableArrayExtra(EXTRA_PROVISIONING_DISCLAIMERS));
    242 
    243             String deviceAdminLabel = null;
    244             String organizationName = null;
    245             String supportUrl = null;
    246             String deviceAdminIconFilePath = null;
    247             if (isProvisionManagedDeviceFromTrustedSourceIntent) {
    248                 deviceAdminLabel = intent.getStringExtra(
    249                         EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL);
    250                 organizationName = intent.getStringExtra(EXTRA_PROVISIONING_ORGANIZATION_NAME);
    251                 supportUrl = intent.getStringExtra(EXTRA_PROVISIONING_SUPPORT_URL);
    252                 deviceAdminIconFilePath = new DeviceAdminIconParser(context, provisioningId).parse(
    253                         intent.getParcelableExtra(
    254                                 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI));
    255             }
    256 
    257             final boolean leaveAllSystemAppsEnabled = isManagedProfileAction
    258                     ? false
    259                     : intent.getBooleanExtra(
    260                             EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
    261                             ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED);
    262 
    263             return ProvisioningParams.Builder.builder()
    264                     .setProvisioningId(provisioningId)
    265                     .setProvisioningAction(provisioningAction)
    266                     .setDeviceAdminComponentName(deviceAdminComponentName)
    267                     .setDeviceAdminPackageName(deviceAdminPackageName)
    268                     .setSkipEncryption(intent.getBooleanExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION,
    269                             ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION))
    270                     .setLeaveAllSystemAppsEnabled(leaveAllSystemAppsEnabled)
    271                     .setAdminExtrasBundle((PersistableBundle) intent.getParcelableExtra(
    272                             EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE))
    273                     .setMainColor(mainColor)
    274                     .setDisclaimersParam(disclaimersParam)
    275                     .setSkipUserConsent(skipUserConsent)
    276                     .setKeepAccountMigrated(keepAccountMigrated)
    277                     .setSkipUserSetup(skipUserSetup)
    278                     .setAccountToMigrate(intent.getParcelableExtra(
    279                             EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE))
    280                     .setDeviceAdminLabel(deviceAdminLabel)
    281                     .setOrganizationName(organizationName)
    282                     .setSupportUrl(supportUrl)
    283                     .setDeviceAdminIconFilePath(deviceAdminIconFilePath);
    284         } catch (ClassCastException e) {
    285             throw new IllegalProvisioningArgumentException("Extra has invalid type", e);
    286         } catch (IllegalArgumentException e) {
    287             throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
    288         } catch (NullPointerException e) {
    289             throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
    290         }
    291     }
    292 
    293     /**
    294      * Parses an intent and return a corresponding {@link ProvisioningParams} object.
    295      *
    296      * @param intent intent to be parsed.
    297      * @param context a context
    298      */
    299     private ProvisioningParams parseAllSupportedProvisioningData(Intent intent, Context context)
    300             throws IllegalProvisioningArgumentException {
    301         try {
    302             ProvisionLogger.logi("Processing all supported extras intent: " + intent.getAction());
    303             return parseMinimalistSupportedProvisioningDataInternal(intent, context)
    304                     // Parse time zone, local time and locale.
    305                     .setTimeZone(intent.getStringExtra(EXTRA_PROVISIONING_TIME_ZONE))
    306                     .setLocalTime(intent.getLongExtra(EXTRA_PROVISIONING_LOCAL_TIME,
    307                             ProvisioningParams.DEFAULT_LOCAL_TIME))
    308                     .setLocale(StoreUtils.stringToLocale(
    309                             intent.getStringExtra(EXTRA_PROVISIONING_LOCALE)))
    310                     .setUseMobileData(intent.getBooleanExtra(EXTRA_PROVISIONING_USE_MOBILE_DATA,
    311                             DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA))
    312                     // Parse WiFi configuration.
    313                     .setWifiInfo(parseWifiInfoFromExtras(intent))
    314                     // Parse device admin package download info.
    315                     .setDeviceAdminDownloadInfo(parsePackageDownloadInfoFromExtras(intent))
    316                     // Cases where startedByTrustedSource can be true are
    317                     // 1. We are reloading a stored provisioning intent, either Nfc bump or
    318                     //    PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE, after encryption reboot,
    319                     //    which is a self-originated intent.
    320                     // 2. the intent is from a trusted source, for example QR provisioning.
    321                     .setStartedByTrustedSource(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE
    322                             .equals(intent.getAction()))
    323                     .build();
    324         }  catch (IllegalArgumentException e) {
    325             throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
    326         }  catch (IllformedLocaleException e) {
    327             throw new IllegalProvisioningArgumentException("Invalid locale format!", e);
    328         }  catch (NullPointerException e) {
    329             throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
    330         }
    331     }
    332 
    333     /**
    334      * Parses Wifi configuration from an Intent and returns the result in {@link WifiInfo}.
    335      */
    336     @Nullable
    337     private WifiInfo parseWifiInfoFromExtras(Intent intent) {
    338         if (intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID) == null) {
    339             return null;
    340         }
    341         return WifiInfo.Builder.builder()
    342                 .setSsid(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID))
    343                 .setSecurityType(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE))
    344                 .setPassword(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PASSWORD))
    345                 .setProxyHost(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_HOST))
    346                 .setProxyBypassHosts(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS))
    347                 .setPacUrl(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PAC_URL))
    348                 .setProxyPort(intent.getIntExtra(EXTRA_PROVISIONING_WIFI_PROXY_PORT,
    349                         WifiInfo.DEFAULT_WIFI_PROXY_PORT))
    350                 .setHidden(intent.getBooleanExtra(EXTRA_PROVISIONING_WIFI_HIDDEN,
    351                         WifiInfo.DEFAULT_WIFI_HIDDEN))
    352                 .build();
    353     }
    354 
    355     /**
    356      * Parses device admin package download info configuration from an Intent and returns the result
    357      * in {@link PackageDownloadInfo}.
    358      */
    359     @Nullable
    360     private PackageDownloadInfo parsePackageDownloadInfoFromExtras(Intent intent) {
    361         if (intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)
    362                 == null) {
    363             return null;
    364         }
    365         PackageDownloadInfo.Builder downloadInfoBuilder = PackageDownloadInfo.Builder.builder()
    366                 .setMinVersion(intent.getIntExtra(
    367                         EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
    368                         PackageDownloadInfo.DEFAULT_MINIMUM_VERSION))
    369                 .setLocation(intent.getStringExtra(
    370                         EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION))
    371                 .setCookieHeader(intent.getStringExtra(
    372                         EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER));
    373         String packageHash =
    374                 intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
    375         if (packageHash != null) {
    376             downloadInfoBuilder.setPackageChecksum(StoreUtils.stringToByteArray(packageHash));
    377         }
    378         String sigHash = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM);
    379         if (sigHash != null) {
    380             downloadInfoBuilder.setSignatureChecksum(StoreUtils.stringToByteArray(sigHash));
    381         }
    382         return downloadInfoBuilder.build();
    383     }
    384 
    385     /**
    386      * Parses the organization logo url from intent.
    387      */
    388     private void parseOrganizationLogoUrlFromExtras(Context context, Intent intent) {
    389         Uri logoUri = intent.getParcelableExtra(EXTRA_PROVISIONING_LOGO_URI);
    390         if (logoUri != null) {
    391             // If we go through encryption, and if the uri is a content uri:
    392             // We'll lose the grant to this uri. So we need to save it to a local file.
    393             LogoUtils.saveOrganisationLogo(context, logoUri);
    394         }
    395     }
    396 }
    397