17079df5a3fb155947004843ee8ec25b36127e3edSteven Ng/*
27079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Copyright 2016, The Android Open Source Project
37079df5a3fb155947004843ee8ec25b36127e3edSteven Ng *
47079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Licensed under the Apache License, Version 2.0 (the "License");
57079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * you may not use this file except in compliance with the License.
67079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * You may obtain a copy of the License at
77079df5a3fb155947004843ee8ec25b36127e3edSteven Ng *
87079df5a3fb155947004843ee8ec25b36127e3edSteven Ng *     http://www.apache.org/licenses/LICENSE-2.0
97079df5a3fb155947004843ee8ec25b36127e3edSteven Ng *
107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Unless required by applicable law or agreed to in writing, software
117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * distributed under the License is distributed on an "AS IS" BASIS,
127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * See the License for the specific language governing permissions and
147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * limitations under the License.
157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */
167079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
177079df5a3fb155947004843ee8ec25b36127e3edSteven Ngpackage com.android.managedprovisioning.parser;
187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
197079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
207079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
217079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
227079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE;
237079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
247079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
257079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
267079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
277079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE;
287079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
297079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER;
307079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
317079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
327079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM;
337079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
347079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
357079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
367079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR;
377079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
387079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_SETUP;
397079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
407079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
417079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
427079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
437079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
447079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST;
457079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT;
467079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
477079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
487079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI;
497079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.internal.util.Preconditions.checkNotNull;
507079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING;
517079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.managedprovisioning.parser.MessageParser.EXTRA_PROVISIONING_ACTION;
527079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.managedprovisioning.parser.MessageParser.EXTRA_PROVISIONING_DEVICE_ADMIN_SUPPORT_SHA1_PACKAGE_CHECKSUM;
537079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.managedprovisioning.parser.MessageParser.EXTRA_PROVISIONING_STARTED_BY_TRUSTED_SOURCE;
547079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
557079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.accounts.Account;
567079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.ComponentName;
577079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.Context;
587079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.Intent;
597079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.net.Uri;
607079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.graphics.Color;
617079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.os.Bundle;
627079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.os.PersistableBundle;
637079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.support.annotation.Nullable;
647079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.support.annotation.VisibleForTesting;
657079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
667079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.LogoUtils;
677079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.ProvisionLogger;
687079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
697079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.common.Utils;
707079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.PackageDownloadInfo;
717079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.ProvisioningParams;
727079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.WifiInfo;
737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
747079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.Arrays;
757079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.HashSet;
767079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.IllformedLocaleException;
777079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.Locale;
787079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.Properties;
797079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.Set;
807079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
817079df5a3fb155947004843ee8ec25b36127e3edSteven Ng/**
827079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * A parser which parses provisioning data from intent which stores in {@link Bundle} extras.
837079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */
847079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
857079df5a3fb155947004843ee8ec25b36127e3edSteven Ng@VisibleForTesting
867079df5a3fb155947004843ee8ec25b36127e3edSteven Ngpublic class ExtrasProvisioningDataParser implements ProvisioningDataParser {
877079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA =
887079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            new HashSet(Arrays.asList(
897079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_RESUME_PROVISIONING,
907079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE));
917079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
927079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private static final Set<String> PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA =
937079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            new HashSet(Arrays.asList(
947079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_PROVISION_MANAGED_DEVICE,
957079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
967079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_PROVISION_MANAGED_USER,
977079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ACTION_PROVISION_MANAGED_PROFILE));
987079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
997079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private final Utils mUtils;
1007079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1017079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    ExtrasProvisioningDataParser(Utils utils) {
1027079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        mUtils = checkNotNull(utils);
1037079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
1047079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1057079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    @Override
1067079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    public ProvisioningParams parse(Intent provisioningIntent, Context context)
1077079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throws IllegalProvisioningArgumentException{
1087079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        String provisioningAction = provisioningIntent.getAction();
1097079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (PROVISIONING_ACTIONS_SUPPORT_MIN_PROVISIONING_DATA.contains(provisioningAction)) {
1117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            ProvisionLogger.logi("Processing mininalist extras intent.");
1127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return parseMinimalistSupportedProvisioningDataInternal(provisioningIntent, context)
1137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .build();
1147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } else if (PROVISIONING_ACTIONS_SUPPORT_ALL_PROVISIONING_DATA.contains(
1157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                provisioningAction)) {
1167079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return parseAllSupportedProvisioningData(provisioningIntent, context);
1177079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } else {
1187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Unsupported provisioning action: "
1197079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    + provisioningAction);
1207079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
1217079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
1227079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1237079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    /**
1247079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * Parses minimal supported set of parameters from bundle extras of a provisioning intent.
1257079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *
1267079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * <p>Here is the list of supported parameters.
1277079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * <ul>
1287079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
1297079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>
1307079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *         {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} only in
1317079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *         {@link ACTION_PROVISION_MANAGED_PROFILE}.
1327079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     </li>
1337079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_LOGO_URI}</li>
1347079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_MAIN_COLOR}</li>
1357079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>
1367079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *         {@link EXTRA_PROVISIONING_SKIP_USER_SETUP} only in
1377079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *         {@link ACTION_PROVISION_MANAGED_USER} and {@link ACTION_PROVISION_MANAGED_DEVICE}.
1387079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     </li>
1397079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_SKIP_ENCRYPTION}</li>
1407079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}</li>
1417079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE}</li>
1427079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *     <li>{@link EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}</li>
1437079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * </ul>
1447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     */
1457079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private ProvisioningParams.Builder parseMinimalistSupportedProvisioningDataInternal(
1467079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            Intent intent, Context context)
1477079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throws IllegalProvisioningArgumentException {
148f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng        boolean isProvisionManagedDeviceFromTrustedSourceIntent =
149f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng                ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(intent.getAction());
1507079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        try {
1517079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            String provisioningAction = isResumeProvisioningIntent(intent)
1527079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    ? intent.getStringExtra(EXTRA_PROVISIONING_ACTION)
1537079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    : mUtils.mapIntentToDpmAction(intent);
1547079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1557079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // Parse device admin package name and component name.
1567079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            ComponentName deviceAdminComponentName = (ComponentName) intent.getParcelableExtra(
1577079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
1587079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // Device admin package name is deprecated. It is only supported in Profile Owner
15990ebb8c38087dcdce28492869befa6d46cdd407bBenjamin Franz            // provisioning and when resuming NFC provisioning.
1607079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            String deviceAdminPackageName = null;
1617079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            if (ACTION_PROVISION_MANAGED_PROFILE.equals(provisioningAction)) {
1627079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // In L, we only support package name. This means some DPC may still send us the
1637079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // device admin package name only. Attempts to obtain the package name from extras.
1647079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                deviceAdminPackageName = intent.getStringExtra(
1657079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
1667079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // For profile owner, the device admin package should be installed. Verify the
1677079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // device admin package.
1687079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                deviceAdminComponentName = mUtils.findDeviceAdmin(
1697079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        deviceAdminPackageName, deviceAdminComponentName, context);
1707079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // Since the device admin package must be installed at this point and its component
1717079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // name has been obtained, it should be safe to set the deprecated package name
1727079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // value to null.
1737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                deviceAdminPackageName = null;
17490ebb8c38087dcdce28492869befa6d46cdd407bBenjamin Franz            } else if (isResumeProvisioningIntent(intent)) {
17590ebb8c38087dcdce28492869befa6d46cdd407bBenjamin Franz                deviceAdminPackageName = intent.getStringExtra(
17690ebb8c38087dcdce28492869befa6d46cdd407bBenjamin Franz                        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
1777079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            }
1787079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
1797079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // Parse skip user setup in ACTION_PROVISION_MANAGED_USER and
180a4d4f7e68706cff4420cdc846541eded95a2984eBenjamin Franz            // ACTION_PROVISION_MANAGED_DEVICE (sync auth) only. This extra is not supported if
181a4d4f7e68706cff4420cdc846541eded95a2984eBenjamin Franz            // provisioning was started by trusted source, as it is not clear where SUW should
182a4d4f7e68706cff4420cdc846541eded95a2984eBenjamin Franz            // continue from.
1837079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            boolean skipUserSetup = ProvisioningParams.DEFAULT_SKIP_USER_SETUP;
184f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            if (!isProvisionManagedDeviceFromTrustedSourceIntent
185a4d4f7e68706cff4420cdc846541eded95a2984eBenjamin Franz                    && (provisioningAction.equals(ACTION_PROVISION_MANAGED_USER)
186a4d4f7e68706cff4420cdc846541eded95a2984eBenjamin Franz                            || provisioningAction.equals(ACTION_PROVISION_MANAGED_DEVICE))) {
1877079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                skipUserSetup = intent.getBooleanExtra(EXTRA_PROVISIONING_SKIP_USER_SETUP,
1887079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        ProvisioningParams.DEFAULT_SKIP_USER_SETUP);
1897079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            }
1907079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
191f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            // Parse main color and organization's logo. This is not supported in managed device
192f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            // from trusted source provisioning because, currently, there is no way to send
193f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            // organization logo to the device at this stage.
194f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            Integer mainColor = ProvisioningParams.DEFAULT_MAIN_COLOR;
195f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            if (!isProvisionManagedDeviceFromTrustedSourceIntent) {
196f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng                if (intent.hasExtra(EXTRA_PROVISIONING_MAIN_COLOR)) {
197f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng                    mainColor = intent.getIntExtra(EXTRA_PROVISIONING_MAIN_COLOR, 0 /* not used */);
198f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng                }
199f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng                parseOrganizationLogoUrlFromExtras(context, intent);
200f9e7d3b02b4b660abf25ace7711f0c483e588388Steven Ng            }
2017079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
2027079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return ProvisioningParams.Builder.builder()
2037079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setProvisioningAction(provisioningAction)
2047079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setDeviceAdminComponentName(deviceAdminComponentName)
2057079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setDeviceAdminPackageName(deviceAdminPackageName)
2067079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setSkipEncryption(intent.getBooleanExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION,
2077079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION))
2087079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setLeaveAllSystemAppsEnabled(intent.getBooleanExtra(
2097079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
2107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED))
2117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setAdminExtrasBundle((PersistableBundle) intent.getParcelableExtra(
2127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE))
2137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setMainColor(mainColor)
2147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setSkipUserSetup(skipUserSetup)
2157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setAccountToMigrate((Account) intent.getParcelableExtra(
2167079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE));
2177079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } catch (ClassCastException e) {
2187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Extra "
2197079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    + EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
2207079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    + " must be of type PersistableBundle.", e);
2217079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } catch (IllegalArgumentException e) {
2227079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
2237079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } catch (NullPointerException e) {
2247079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
2257079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
2267079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
2277079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
2287079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    /**
2297079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * Parses an intent and return a corresponding {@link ProvisioningParams} object.
2307079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     *
2317079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * @param intent intent to be parsed.
2327079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * @param context a context
2337079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     */
2347079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private ProvisioningParams parseAllSupportedProvisioningData(Intent intent, Context context)
2357079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throws IllegalProvisioningArgumentException {
2367079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        try {
2377079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            ProvisionLogger.logi("Processing all supported extras intent: " + intent.getAction());
2387079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return parseMinimalistSupportedProvisioningDataInternal(intent, context)
2397079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // Parse time zone, local time and locale.
2407079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setTimeZone(intent.getStringExtra(EXTRA_PROVISIONING_TIME_ZONE))
2417079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setLocalTime(intent.getLongExtra(EXTRA_PROVISIONING_LOCAL_TIME,
2427079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            ProvisioningParams.DEFAULT_LOCAL_TIME))
2437079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setLocale(MessageParser.stringToLocale(
2447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            intent.getStringExtra(EXTRA_PROVISIONING_LOCALE)))
2457079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // Parse WiFi configuration.
2467079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setWifiInfo(parseWifiInfoFromExtras(intent))
2477079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // Parse device admin package download info.
2487079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setDeviceAdminDownloadInfo(parsePackageDownloadInfoFromExtras(intent))
2497079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // Cases where startedByTrustedSource can be true are
2507079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // 1. We are reloading a stored provisioning intent, either Nfc bump or
2517079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    //    PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE, after encryption reboot,
2527079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    //    which is a self-originated intent.
2537079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    // 2. the intent is from a trusted source, for example QR provisioning.
2547079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .setStartedByTrustedSource(isResumeProvisioningIntent(intent)
2557079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            ? intent.getBooleanExtra(EXTRA_PROVISIONING_STARTED_BY_TRUSTED_SOURCE,
2567079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                                    ProvisioningParams.DEFAULT_STARTED_BY_TRUSTED_SOURCE)
2577079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                            : ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE.equals(
2587079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                                    intent.getAction()))
2597079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                    .build();
2607079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }  catch (IllegalArgumentException e) {
2617079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Invalid parameter found!", e);
2627079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } catch (NullPointerException e) {
2637079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            throw new IllegalProvisioningArgumentException("Compulsory parameter not found!", e);
2647079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
2657079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
2667079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
2677079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    /**
2687079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * Parses Wifi configuration from an Intent and returns the result in {@link WifiInfo}.
2697079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     */
2707079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    @Nullable
2717079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private WifiInfo parseWifiInfoFromExtras(Intent intent) {
2727079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID) == null) {
2737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return null;
2747079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
2757079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        return WifiInfo.Builder.builder()
2767079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setSsid(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID))
2777079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setSecurityType(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE))
2787079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setPassword(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PASSWORD))
2797079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setProxyHost(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_HOST))
2807079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setProxyBypassHosts(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS))
2817079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setPacUrl(intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PAC_URL))
2827079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setProxyPort(intent.getIntExtra(EXTRA_PROVISIONING_WIFI_PROXY_PORT,
2837079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        WifiInfo.DEFAULT_WIFI_PROXY_PORT))
2847079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setHidden(intent.getBooleanExtra(EXTRA_PROVISIONING_WIFI_HIDDEN,
2857079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        WifiInfo.DEFAULT_WIFI_HIDDEN))
2867079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .build();
2877079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
2887079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
2897079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    /**
2907079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * Parses device admin package download info configuration from an Intent and returns the result
2917079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * in {@link PackageDownloadInfo}.
2927079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     */
2937079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    @Nullable
2947079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private PackageDownloadInfo parsePackageDownloadInfoFromExtras(Intent intent) {
2957079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)
2967079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                == null) {
2977079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            return null;
2987079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
2997079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        PackageDownloadInfo.Builder downloadInfoBuilder = PackageDownloadInfo.Builder.builder()
3007079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setMinVersion(intent.getIntExtra(
3017079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE,
3027079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        PackageDownloadInfo.DEFAULT_MINIMUM_VERSION))
3037079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setLocation(intent.getStringExtra(
3047079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION))
3057079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                .setCookieHeader(intent.getStringExtra(
3067079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER));
3077079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        String packageHash =
3087079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
3097079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (packageHash != null) {
3107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            downloadInfoBuilder.setPackageChecksum(mUtils.stringToByteArray(packageHash));
3117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            if (isResumeProvisioningIntent(intent)) {
3127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // PackageChecksumSupportsSha1 is only supported in NFC provisioning. But if the
3137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // device is rebooted after encryption as part of the NFC provisioning flow, the
3147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                // value should be restored.
3157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                downloadInfoBuilder.setPackageChecksumSupportsSha1(
3167079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                        intent.getBooleanExtra(
3177079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                                EXTRA_PROVISIONING_DEVICE_ADMIN_SUPPORT_SHA1_PACKAGE_CHECKSUM,
3187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng                                false));
3197079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            }
3207079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
3217079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        String sigHash = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM);
3227079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (sigHash != null) {
3237079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            downloadInfoBuilder.setSignatureChecksum(mUtils.stringToByteArray(sigHash));
3247079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
3257079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        return downloadInfoBuilder.build();
3267079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
3277079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
3287079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    /**
3297079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     * Parses the organization logo url from intent.
3307079df5a3fb155947004843ee8ec25b36127e3edSteven Ng     */
3317079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private void parseOrganizationLogoUrlFromExtras(Context context, Intent intent) {
3327079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        Uri logoUri = intent.getParcelableExtra(EXTRA_PROVISIONING_LOGO_URI);
3337079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        if (logoUri != null) {
3347079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // If we go through encryption, and if the uri is a content uri:
3357079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // We'll lose the grant to this uri. So we need to save it to a local file.
3367079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            LogoUtils.saveOrganisationLogo(context, logoUri);
3377079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        } else if (!isResumeProvisioningIntent(intent)) {
3387079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // If the intent is not from managed provisioning app, there is a slight possibility
3397079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // that the logo is still kept on the file system from a previous provisioning. In
3407079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            // this case, remove it.
3417079df5a3fb155947004843ee8ec25b36127e3edSteven Ng            LogoUtils.cleanUp(context);
3427079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        }
3437079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
3447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng
3457079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    private boolean isResumeProvisioningIntent(Intent intent) {
3467079df5a3fb155947004843ee8ec25b36127e3edSteven Ng        return ACTION_RESUME_PROVISIONING.equals(intent.getAction());
3477079df5a3fb155947004843ee8ec25b36127e3edSteven Ng    }
3487079df5a3fb155947004843ee8ec25b36127e3edSteven Ng}
349