| /* |
| * 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_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_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_KEEP_SCREEN_ON; |
| 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_SENSORS_PERMISSION_GRANT_OPT_OUT; |
| 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 { |
| 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) |
| .setKeepScreenOn(getBooleanExtraFromLongName( |
| intent, |
| EXTRA_PROVISIONING_KEEP_SCREEN_ON, |
| ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_KEEP_SCREEN_ON)); |
| } 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 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 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(); |
| } |
| } |