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.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 207079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME; 217079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE; 227079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM; 237079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER; 247079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION; 257079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME; 267079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM; 277079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED; 287079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE; 297079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME; 307079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION; 317079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE; 327079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN; 337079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL; 347079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD; 357079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS; 367079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST; 377079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT; 387079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE; 397079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID; 407079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC; 417079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED; 427079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static com.android.internal.util.Preconditions.checkNotNull; 437079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport static java.nio.charset.StandardCharsets.UTF_8; 447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 457079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.ComponentName; 467079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.Context; 477079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.content.Intent; 487079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.nfc.NdefMessage; 497079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.nfc.NdefRecord; 507079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.nfc.NfcAdapter; 517079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.os.Parcelable; 527079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.os.PersistableBundle; 537079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.support.annotation.Nullable; 547079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport android.support.annotation.VisibleForTesting; 5590f58ca887207a527c80d7e9ccea97e205c960d4Victor Changimport com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 56f7a9eea8fe577f2f5edbbe6e73891a54351286c6Benjamin Franzimport com.android.managedprovisioning.common.ProvisionLogger; 577079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 58d2aa11e5484f3e56cea4ac328b2a0a58c28d4047Nicolas Prevotimport com.android.managedprovisioning.common.StoreUtils; 597079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.common.Utils; 607079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.PackageDownloadInfo; 617079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.ProvisioningParams; 627079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.model.WifiInfo; 637079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.io.IOException; 647079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.io.StringReader; 657079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.IllformedLocaleException; 667079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport java.util.Properties; 677079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 687079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 697079df5a3fb155947004843ee8ec25b36127e3edSteven Ng/** 707079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * A parser which parses provisioning data from intent which stores in {@link Properties}. 717079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * 727079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * <p>It is used to parse an intent contains the extra {@link NfcAdapter.EXTRA_NDEF_MESSAGES}, which 737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * indicates that provisioning was started via Nfc bump. This extra contains an NDEF message, which 747079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * contains an NfcRecord with mime type {@link MIME_TYPE_PROVISIONING_NFC}. This record stores a 757079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * serialized properties object, which contains the serialized extras described in the next option. 767079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * A typical use case would be a programmer application that sends an Nfc bump to start Nfc 777079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * provisioning from a programmer device. 787079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */ 797079df5a3fb155947004843ee8ec25b36127e3edSteven Ng@VisibleForTesting 807079df5a3fb155947004843ee8ec25b36127e3edSteven Ngpublic class PropertiesProvisioningDataParser implements ProvisioningDataParser { 817079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 827079df5a3fb155947004843ee8ec25b36127e3edSteven Ng private final Utils mUtils; 8390f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang private final Context mContext; 8490f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang private final ManagedProvisioningSharedPreferences mSharedPreferences; 857079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 8690f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang PropertiesProvisioningDataParser(Context context, Utils utils) { 8790f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang this(context, utils, new ManagedProvisioningSharedPreferences(context)); 8890f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang } 8990f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang 9090f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang @VisibleForTesting 9190f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang PropertiesProvisioningDataParser(Context context, Utils utils, 9290f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang ManagedProvisioningSharedPreferences sharedPreferences) { 9390f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang mContext = checkNotNull(context); 947079df5a3fb155947004843ee8ec25b36127e3edSteven Ng mUtils = checkNotNull(utils); 9590f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang mSharedPreferences = checkNotNull(sharedPreferences); 967079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 977079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 9890f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang public ProvisioningParams parse(Intent nfcIntent) 997079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throws IllegalProvisioningArgumentException { 1007079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if (!ACTION_NDEF_DISCOVERED.equals(nfcIntent.getAction())) { 1017079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException( 1027079df5a3fb155947004843ee8ec25b36127e3edSteven Ng "Only NFC action is supported in this parser."); 1037079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1047079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1057079df5a3fb155947004843ee8ec25b36127e3edSteven Ng ProvisionLogger.logi("Processing Nfc Payload."); 1067079df5a3fb155947004843ee8ec25b36127e3edSteven Ng NdefRecord firstRecord = getFirstNdefRecord(nfcIntent); 1077079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if (firstRecord != null) { 1087079df5a3fb155947004843ee8ec25b36127e3edSteven Ng try { 1097079df5a3fb155947004843ee8ec25b36127e3edSteven Ng Properties props = new Properties(); 1107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng props.load(new StringReader(new String(firstRecord.getPayload(), UTF_8))); 1117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // For parsing non-string parameters. 1137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng String s = null; 1147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng ProvisioningParams.Builder builder = ProvisioningParams.Builder.builder() 11690f58ca887207a527c80d7e9ccea97e205c960d4Victor Chang .setProvisioningId(mSharedPreferences.incrementAndGetProvisioningId()) 1177079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setStartedByTrustedSource(true) 1187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setProvisioningAction(mUtils.mapIntentToDpmAction(nfcIntent)) 1197079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setDeviceAdminPackageName(props.getProperty( 1207079df5a3fb155947004843ee8ec25b36127e3edSteven Ng EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME)); 1217079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME)) 1227079df5a3fb155947004843ee8ec25b36127e3edSteven Ng != null) { 1237079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setDeviceAdminComponentName(ComponentName.unflattenFromString(s)); 1247079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1257079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1267079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Parse time zone, locale and local time. 1277079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setTimeZone(props.getProperty(EXTRA_PROVISIONING_TIME_ZONE)) 128d2aa11e5484f3e56cea4ac328b2a0a58c28d4047Nicolas Prevot .setLocale(StoreUtils.stringToLocale( 1297079df5a3fb155947004843ee8ec25b36127e3edSteven Ng props.getProperty(EXTRA_PROVISIONING_LOCALE))); 1307079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_LOCAL_TIME)) != null) { 1317079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setLocalTime(Long.parseLong(s)); 1327079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1337079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1347079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Parse WiFi configuration. 1357079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setWifiInfo(parseWifiInfoFromProperties(props)) 1367079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Parse device admin package download info. 1377079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setDeviceAdminDownloadInfo(parsePackageDownloadInfoFromProperties(props)) 1387079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Parse EMM customized key-value pairs. 1397079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Note: EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE property contains a 1407079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Properties object serialized into String. See Properties.store() and 1417079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Properties.load() for more details. The property value is optional. 1427079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setAdminExtrasBundle(deserializeExtrasBundle(props, 1437079df5a3fb155947004843ee8ec25b36127e3edSteven Ng EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)); 1447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED)) 1457079df5a3fb155947004843ee8ec25b36127e3edSteven Ng != null) { 1467079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setLeaveAllSystemAppsEnabled(Boolean.parseBoolean(s)); 1477079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1487079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_SKIP_ENCRYPTION)) != null) { 1497079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setSkipEncryption(Boolean.parseBoolean(s)); 1507079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1517079df5a3fb155947004843ee8ec25b36127e3edSteven Ng ProvisionLogger.logi("End processing Nfc Payload."); 1527079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return builder.build(); 1537079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } catch (IOException e) { 1547079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException("Couldn't load payload", e); 1557079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } catch (NumberFormatException e) { 1567079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException("Incorrect numberformat.", e); 1577079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } catch (IllformedLocaleException e) { 1587079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException("Invalid locale.", e); 1597079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } catch (IllegalArgumentException e) { 1607079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException("Invalid parameter found!", e); 1617079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } catch (NullPointerException e) { 1627079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException( 1637079df5a3fb155947004843ee8ec25b36127e3edSteven Ng "Compulsory parameter not found!", e); 1647079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1657079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1667079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throw new IllegalProvisioningArgumentException( 1677079df5a3fb155947004843ee8ec25b36127e3edSteven Ng "Intent does not contain NfcRecord with the correct MIME type."); 1687079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1697079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1707079df5a3fb155947004843ee8ec25b36127e3edSteven Ng /** 1717079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Parses Wifi configuration from an {@link Properties} and returns the result in 1727079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * {@link WifiInfo}. 1737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */ 1747079df5a3fb155947004843ee8ec25b36127e3edSteven Ng @Nullable 1757079df5a3fb155947004843ee8ec25b36127e3edSteven Ng private WifiInfo parseWifiInfoFromProperties(Properties props) { 1767079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if (props.getProperty(EXTRA_PROVISIONING_WIFI_SSID) == null) { 1777079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return null; 1787079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1797079df5a3fb155947004843ee8ec25b36127e3edSteven Ng WifiInfo.Builder builder = WifiInfo.Builder.builder() 1807079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setSsid(props.getProperty(EXTRA_PROVISIONING_WIFI_SSID)) 1817079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setSecurityType(props.getProperty(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE)) 1827079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setPassword(props.getProperty(EXTRA_PROVISIONING_WIFI_PASSWORD)) 1837079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setProxyHost(props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_HOST)) 1847079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setProxyBypassHosts(props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS)) 1857079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setPacUrl(props.getProperty(EXTRA_PROVISIONING_WIFI_PAC_URL)); 1867079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // For parsing non-string parameters. 1877079df5a3fb155947004843ee8ec25b36127e3edSteven Ng String s = null; 1887079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_PORT)) != null) { 1897079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setProxyPort(Integer.parseInt(s)); 1907079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1917079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_HIDDEN)) != null) { 1927079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setHidden(Boolean.parseBoolean(s)); 1937079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1947079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1957079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return builder.build(); 1967079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 1977079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 1987079df5a3fb155947004843ee8ec25b36127e3edSteven Ng /** 1997079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Parses device admin package download info from an {@link Properties} and returns the result 2007079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * in {@link PackageDownloadInfo}. 2017079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */ 2027079df5a3fb155947004843ee8ec25b36127e3edSteven Ng @Nullable 2037079df5a3fb155947004843ee8ec25b36127e3edSteven Ng private PackageDownloadInfo parsePackageDownloadInfoFromProperties(Properties props) { 2047079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if (props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION) == null) { 2057079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return null; 2067079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2077079df5a3fb155947004843ee8ec25b36127e3edSteven Ng PackageDownloadInfo.Builder builder = PackageDownloadInfo.Builder.builder() 2087079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setLocation(props.getProperty( 2097079df5a3fb155947004843ee8ec25b36127e3edSteven Ng EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION)) 2107079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setCookieHeader(props.getProperty( 2117079df5a3fb155947004843ee8ec25b36127e3edSteven Ng EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER)); 2127079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // For parsing non-string parameters. 2137079df5a3fb155947004843ee8ec25b36127e3edSteven Ng String s = null; 2147079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE)) != null) { 2157079df5a3fb155947004843ee8ec25b36127e3edSteven Ng builder.setMinVersion(Integer.parseInt(s)); 2167079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2177079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)) != null) { 2187079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Still support SHA-1 for device admin package hash if we are provisioned by a Nfc 2197079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // programmer. 2207079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // TODO: remove once SHA-1 is fully deprecated. 221d2aa11e5484f3e56cea4ac328b2a0a58c28d4047Nicolas Prevot builder.setPackageChecksum(StoreUtils.stringToByteArray(s)) 2227079df5a3fb155947004843ee8ec25b36127e3edSteven Ng .setPackageChecksumSupportsSha1(true); 2237079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2247079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM)) 2257079df5a3fb155947004843ee8ec25b36127e3edSteven Ng != null) { 226d2aa11e5484f3e56cea4ac328b2a0a58c28d4047Nicolas Prevot builder.setSignatureChecksum(StoreUtils.stringToByteArray(s)); 2277079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2287079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return builder.build(); 2297079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2307079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 2317079df5a3fb155947004843ee8ec25b36127e3edSteven Ng /** 2327079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * Get a {@link PersistableBundle} from a String property in a Properties object. 2337079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * @param props the source of the extra 2347079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * @param extraName key into the Properties object 2357079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * @return the bundle or {@code null} if there was no property with the given name 2367079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * @throws IOException if there was an error parsing the propery 2377079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */ 2387079df5a3fb155947004843ee8ec25b36127e3edSteven Ng private PersistableBundle deserializeExtrasBundle(Properties props, String extraName) 2397079df5a3fb155947004843ee8ec25b36127e3edSteven Ng throws IOException { 2407079df5a3fb155947004843ee8ec25b36127e3edSteven Ng PersistableBundle extrasBundle = null; 2417079df5a3fb155947004843ee8ec25b36127e3edSteven Ng String serializedExtras = props.getProperty(extraName); 2427079df5a3fb155947004843ee8ec25b36127e3edSteven Ng if (serializedExtras != null) { 2437079df5a3fb155947004843ee8ec25b36127e3edSteven Ng Properties extrasProp = new Properties(); 2447079df5a3fb155947004843ee8ec25b36127e3edSteven Ng extrasProp.load(new StringReader(serializedExtras)); 2457079df5a3fb155947004843ee8ec25b36127e3edSteven Ng extrasBundle = new PersistableBundle(extrasProp.size()); 2467079df5a3fb155947004843ee8ec25b36127e3edSteven Ng for (String propName : extrasProp.stringPropertyNames()) { 2477079df5a3fb155947004843ee8ec25b36127e3edSteven Ng extrasBundle.putString(propName, extrasProp.getProperty(propName)); 2487079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2497079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2507079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return extrasBundle; 2517079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2527079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 2537079df5a3fb155947004843ee8ec25b36127e3edSteven Ng /** 2547079df5a3fb155947004843ee8ec25b36127e3edSteven Ng * @return the first {@link NdefRecord} found with a recognized MIME-type 2557079df5a3fb155947004843ee8ec25b36127e3edSteven Ng */ 2568a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra public static NdefRecord getFirstNdefRecord(Intent nfcIntent) { 2577079df5a3fb155947004843ee8ec25b36127e3edSteven Ng // Only one first message with NFC_MIME_TYPE is used. 2588a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra final Parcelable[] ndefMessages = nfcIntent.getParcelableArrayExtra( 2598a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra NfcAdapter.EXTRA_NDEF_MESSAGES); 2608a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra if (ndefMessages != null) { 2618a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra for (Parcelable rawMsg : ndefMessages) { 2628a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra NdefMessage msg = (NdefMessage) rawMsg; 2638a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra for (NdefRecord record : msg.getRecords()) { 2648a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra String mimeType = new String(record.getType(), UTF_8); 2657079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 2668a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra if (MIME_TYPE_PROVISIONING_NFC.equals(mimeType)) { 2678a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra return record; 2688a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra } 2697079df5a3fb155947004843ee8ec25b36127e3edSteven Ng 2708a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra // Assume only first record of message is used. 2718a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra break; 2728a0cbf851f45b0df553854788a53902619af08f3Mahaver Chopra } 2737079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2747079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2757079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return null; 2767079df5a3fb155947004843ee8ec25b36127e3edSteven Ng } 2777079df5a3fb155947004843ee8ec25b36127e3edSteven Ng} 278