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