blob: 1cb77d76de4dd15a8d02d5e351203636b1e17a3c [file] [log] [blame]
Sander Alewijnseed0883b2014-03-18 15:01:13 +00001/*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.managedprovisioning;
18
Sander Alewijnse56f71572014-06-23 16:21:33 +010019import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
20import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
21import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
22import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
23import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
24import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
25import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
26import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST;
27import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT;
28import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
29import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
Sander Alewijnsef88f7092014-08-20 16:26:09 +010030import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
Sander Alewijnse9aff1402014-07-18 17:15:32 +010031import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
Sander Alewijnse56f71572014-06-23 16:21:33 +010032import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +010033import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER;
Sander Alewijnse56f71572014-06-23 16:21:33 +010034import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
Sander Alewijnsefd134872014-11-18 13:28:06 +000035import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
Esteban Talaverae917d112014-08-20 14:23:53 +010036import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC;
Sander Alewijnse28bffd62014-06-05 10:54:26 +010037import static java.nio.charset.StandardCharsets.UTF_8;
38
Sander Alewijnseed0883b2014-03-18 15:01:13 +000039import android.content.Intent;
40import android.nfc.NdefMessage;
41import android.nfc.NdefRecord;
42import android.nfc.NfcAdapter;
Sander Alewijnse9aff1402014-07-18 17:15:32 +010043import android.os.Bundle;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000044import android.os.Parcelable;
Sander Alewijnsef88f7092014-08-20 16:26:09 +010045import android.os.PersistableBundle;
Sander Alewijnsed7043852014-06-17 15:50:48 +010046import android.text.TextUtils;
Sander Alewijnse48fdbe02014-07-03 14:25:45 +010047import android.util.Base64;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000048
49import java.io.IOException;
50import java.io.StringReader;
51import java.util.Enumeration;
52import java.util.HashMap;
Narayan Kamath53ff3c02014-07-17 14:02:58 +010053import java.util.IllformedLocaleException;
Sander Alewijnse63254f42014-03-21 15:31:12 +000054import java.util.Locale;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000055import java.util.Properties;
56
57/**
Sander Alewijnse8f9bd132014-09-08 12:21:26 +010058 * This class can initialize a {@link ProvisioningParams} object from an intent.
59 * A {@link ProvisioningParams} object stores various parameters for the device owner provisioning.
60 * There are two kinds of intents that can be parsed it into {@link ProvisioningParams}:
Sander Alewijnse28bffd62014-06-05 10:54:26 +010061 *
62 * <p>
Sander Alewijnse56f71572014-06-23 16:21:33 +010063 * Intent was received via Nfc.
64 * The intent contains the extra {@link NfcAdapter.EXTRA_NDEF_MESSAGES}, which indicates that
65 * provisioning was started via Nfc bump. This extra contains an NDEF message, which contains an
Esteban Talaverae917d112014-08-20 14:23:53 +010066 * NfcRecord with mime type {@link MIME_TYPE_PROVISIONING_NFC}. This record stores a serialized
Sander Alewijnse56f71572014-06-23 16:21:33 +010067 * properties object, which contains the serialized extra's described in the next option.
68 * A typical use case would be a programmer application that sends an Nfc bump to start Nfc
69 * provisioning from a programmer device.
Sander Alewijnse28bffd62014-06-05 10:54:26 +010070 *
71 * <p>
Sander Alewijnse56f71572014-06-23 16:21:33 +010072 * Intent was received directly.
73 * The intent contains the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME},
74 * and may contain {@link #EXTRA_PROVISIONING_TIME_ZONE},
75 * {@link #EXTRA_PROVISIONING_LOCAL_TIME}, and {@link #EXTRA_PROVISIONING_LOCALE}. A download
76 * location may be specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +010077 * together with an optional http cookie header
78 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER} accompanied by the SHA-1
79 * sum of the target file {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}.
Sander Alewijnsef88f7092014-08-20 16:26:09 +010080 * Additional information to send through to the device admin may be specified in
81 * {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}.
Sander Alewijnsefd134872014-11-18 13:28:06 +000082 * The boolean {@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED} indicates wheter system
83 * apps should not be disabled.
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +010084 * Furthermore a wifi network may be specified in {@link #EXTRA_PROVISIONING_WIFI_SSID}, and if
85 * applicable {@link #EXTRA_PROVISIONING_WIFI_HIDDEN},
86 * {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE}, {@link #EXTRA_PROVISIONING_WIFI_PASSWORD},
87 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, {@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT},
88 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}.
Sander Alewijnse56f71572014-06-23 16:21:33 +010089 * A typical use case would be the {@link BootReminder} sending the intent after device encryption
90 * and reboot.
Sander Alewijnse9aff1402014-07-18 17:15:32 +010091 *
92 * <p>
Sander Alewijnse8f9bd132014-09-08 12:21:26 +010093 * Furthermore this class can construct the bundle of extras for the second kind of intent given a
94 * {@link ProvisioningParams}, and it keeps track of the types of the extras in the
95 * DEVICE_OWNER_x_EXTRAS, with x the appropriate type.
Sander Alewijnseed0883b2014-03-18 15:01:13 +000096 */
Sander Alewijnse28bffd62014-06-05 10:54:26 +010097public class MessageParser {
Sander Alewijnse8f9bd132014-09-08 12:21:26 +010098 private static final String EXTRA_PROVISIONING_STARTED_BY_NFC =
99 "com.android.managedprovisioning.extra.started_by_nfc";
100
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100101 protected static final String[] DEVICE_OWNER_STRING_EXTRAS = {
102 EXTRA_PROVISIONING_TIME_ZONE,
103 EXTRA_PROVISIONING_LOCALE,
104 EXTRA_PROVISIONING_WIFI_SSID,
105 EXTRA_PROVISIONING_WIFI_SECURITY_TYPE,
106 EXTRA_PROVISIONING_WIFI_PASSWORD,
107 EXTRA_PROVISIONING_WIFI_PROXY_HOST,
108 EXTRA_PROVISIONING_WIFI_PROXY_BYPASS,
109 EXTRA_PROVISIONING_WIFI_PAC_URL,
110 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
111 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100112 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
Sander Alewijnse88d5d0e2014-09-04 12:01:22 +0100113 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100114 };
115
116 protected static final String[] DEVICE_OWNER_LONG_EXTRAS = {
117 EXTRA_PROVISIONING_LOCAL_TIME
118 };
119
120 protected static final String[] DEVICE_OWNER_INT_EXTRAS = {
121 EXTRA_PROVISIONING_WIFI_PROXY_PORT
122 };
123
124 protected static final String[] DEVICE_OWNER_BOOLEAN_EXTRAS = {
Sander Alewijnse8f9bd132014-09-08 12:21:26 +0100125 EXTRA_PROVISIONING_WIFI_HIDDEN,
Sander Alewijnsefd134872014-11-18 13:28:06 +0000126 EXTRA_PROVISIONING_STARTED_BY_NFC,
127 EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100128 };
129
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100130 protected static final String[] DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
131 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
132 };
133
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100134 public void addProvisioningParamsToBundle(Bundle bundle, ProvisioningParams params) {
135 bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, params.mTimeZone);
136 bundle.putString(EXTRA_PROVISIONING_LOCALE, params.getLocaleAsString());
137 bundle.putString(EXTRA_PROVISIONING_WIFI_SSID, params.mWifiSsid);
138 bundle.putString(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, params.mWifiSecurityType);
139 bundle.putString(EXTRA_PROVISIONING_WIFI_PASSWORD, params.mWifiPassword);
140 bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_HOST, params.mWifiProxyHost);
141 bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS, params.mWifiProxyBypassHosts);
142 bundle.putString(EXTRA_PROVISIONING_WIFI_PAC_URL, params.mWifiPacUrl);
143 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
144 params.mDeviceAdminPackageName);
145 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
146 params.mDeviceAdminPackageDownloadLocation);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100147 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
148 params.mDeviceAdminPackageDownloadCookieHeader);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100149 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
150 params.getDeviceAdminPackageChecksumAsString());
151
152 bundle.putLong(EXTRA_PROVISIONING_LOCAL_TIME, params.mLocalTime);
153
154 bundle.putInt(EXTRA_PROVISIONING_WIFI_PROXY_PORT, params.mWifiProxyPort);
155
156 bundle.putBoolean(EXTRA_PROVISIONING_WIFI_HIDDEN, params.mWifiHidden);
Sander Alewijnse8f9bd132014-09-08 12:21:26 +0100157 bundle.putBoolean(EXTRA_PROVISIONING_STARTED_BY_NFC, params.mStartedByNfc);
Sander Alewijnsefd134872014-11-18 13:28:06 +0000158 bundle.putBoolean(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
159 params.mLeaveAllSystemAppsEnabled);
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100160
161 bundle.putParcelable(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, params.mAdminExtrasBundle);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100162 }
163
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100164 public ProvisioningParams parseIntent(Intent intent) throws ParseException {
165 ProvisionLogger.logi("Processing intent.");
166 if (intent.hasExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
167 return parseNfcIntent(intent);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000168 } else {
Sander Alewijnse56f71572014-06-23 16:21:33 +0100169 return parseNonNfcIntent(intent);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000170 }
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000171 }
172
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100173 public ProvisioningParams parseNfcIntent(Intent nfcIntent)
174 throws ParseException {
175 ProvisionLogger.logi("Processing Nfc Payload.");
176 // Only one first message with NFC_MIME_TYPE is used.
177 for (Parcelable rawMsg : nfcIntent
178 .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
179 NdefMessage msg = (NdefMessage) rawMsg;
180
181 // Assume only first record of message is used.
182 NdefRecord firstRecord = msg.getRecords()[0];
183 String mimeType = new String(firstRecord.getType(), UTF_8);
184
Esteban Talaverae917d112014-08-20 14:23:53 +0100185 if (MIME_TYPE_PROVISIONING_NFC.equals(mimeType)) {
Sander Alewijnse8f9bd132014-09-08 12:21:26 +0100186 ProvisioningParams params = parseProperties(new String(firstRecord.getPayload()
187 , UTF_8));
188 params.mStartedByNfc = true;
189 return params;
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100190 }
191 }
192 throw new ParseException(
193 "Intent does not contain NfcRecord with the correct MIME type.",
Bill Yi9182d362014-07-28 10:54:17 -0700194 R.string.device_owner_error_general);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100195 }
196
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100197 // Note: You can't include the EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE in the properties that is
198 // send over Nfc, because there is no publicly documented conversion from PersistableBundle to
199 // String.
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100200 private ProvisioningParams parseProperties(String data)
Sander Alewijnse885c3492014-04-24 17:30:31 +0100201 throws ParseException {
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000202 ProvisioningParams params = new ProvisioningParams();
203 try {
204 Properties props = new Properties();
205 props.load(new StringReader(data));
206
Sander Alewijnse56f71572014-06-23 16:21:33 +0100207 String s; // Used for parsing non-Strings.
Sander Alewijnse56f71572014-06-23 16:21:33 +0100208 params.mTimeZone
209 = props.getProperty(EXTRA_PROVISIONING_TIME_ZONE);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100210 if ((s = props.getProperty(EXTRA_PROVISIONING_LOCALE)) != null) {
211 params.mLocale = stringToLocale(s);
212 }
213 params.mWifiSsid = props.getProperty(EXTRA_PROVISIONING_WIFI_SSID);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100214 params.mWifiSecurityType = props.getProperty(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
215 params.mWifiPassword = props.getProperty(EXTRA_PROVISIONING_WIFI_PASSWORD);
216 params.mWifiProxyHost = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100217 params.mWifiProxyBypassHosts = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
218 params.mWifiPacUrl = props.getProperty(EXTRA_PROVISIONING_WIFI_PAC_URL);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100219 params.mDeviceAdminPackageName
220 = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100221 params.mDeviceAdminPackageDownloadLocation
222 = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100223 params.mDeviceAdminPackageDownloadCookieHeader = props.getProperty(
224 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100225 if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)) != null) {
226 params.mDeviceAdminPackageChecksum = stringToByteArray(s);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000227 }
Sander Alewijnse885c3492014-04-24 17:30:31 +0100228
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100229 if ((s = props.getProperty(EXTRA_PROVISIONING_LOCAL_TIME)) != null) {
230 params.mLocalTime = Long.parseLong(s);
231 }
232
233 if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_PORT)) != null) {
234 params.mWifiProxyPort = Integer.parseInt(s);
235 }
236
237 if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_HIDDEN)) != null) {
238 params.mWifiHidden = Boolean.parseBoolean(s);
239 }
240
Sander Alewijnsefd134872014-11-18 13:28:06 +0000241 if ((s = props.getProperty(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED)) != null) {
242 params.mLeaveAllSystemAppsEnabled = Boolean.parseBoolean(s);
243 }
244
Sander Alewijnse885c3492014-04-24 17:30:31 +0100245 checkValidityOfProvisioningParams(params);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000246 return params;
247 } catch (IOException e) {
Sander Alewijnse885c3492014-04-24 17:30:31 +0100248 throw new ParseException("Couldn't load payload",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100249 R.string.device_owner_error_general, e);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000250 } catch (NumberFormatException e) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100251 throw new ParseException("Incorrect numberformat.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100252 R.string.device_owner_error_general, e);
Narayan Kamath53ff3c02014-07-17 14:02:58 +0100253 } catch (IllformedLocaleException e) {
254 throw new ParseException("Invalid locale.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100255 R.string.device_owner_error_general, e);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000256 }
257 }
258
Sander Alewijnse56f71572014-06-23 16:21:33 +0100259 public ProvisioningParams parseNonNfcIntent(Intent intent)
260 throws ParseException {
261 ProvisionLogger.logi("Processing intent.");
262 ProvisioningParams params = new ProvisioningParams();
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000263
Sander Alewijnse56f71572014-06-23 16:21:33 +0100264 params.mTimeZone = intent.getStringExtra(EXTRA_PROVISIONING_TIME_ZONE);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100265 String localeString = intent.getStringExtra(EXTRA_PROVISIONING_LOCALE);
266 if (localeString != null) {
267 params.mLocale = stringToLocale(localeString);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000268 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100269 params.mWifiSsid = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100270 params.mWifiSecurityType = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
271 params.mWifiPassword = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PASSWORD);
272 params.mWifiProxyHost = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100273 params.mWifiProxyBypassHosts = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
274 params.mWifiPacUrl = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PAC_URL);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100275 params.mDeviceAdminPackageName
276 = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100277 params.mDeviceAdminPackageDownloadLocation
278 = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100279 params.mDeviceAdminPackageDownloadCookieHeader = intent.getStringExtra(
280 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100281 String hashString = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
282 if (hashString != null) {
283 params.mDeviceAdminPackageChecksum = stringToByteArray(hashString);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000284 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100285
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100286 params.mLocalTime = intent.getLongExtra(EXTRA_PROVISIONING_LOCAL_TIME,
287 ProvisioningParams.DEFAULT_LOCAL_TIME);
288
289 params.mWifiProxyPort = intent.getIntExtra(EXTRA_PROVISIONING_WIFI_PROXY_PORT,
290 ProvisioningParams.DEFAULT_WIFI_PROXY_PORT);
291
292 params.mWifiHidden = intent.getBooleanExtra(EXTRA_PROVISIONING_WIFI_HIDDEN,
293 ProvisioningParams.DEFAULT_WIFI_HIDDEN);
Sander Alewijnse8f9bd132014-09-08 12:21:26 +0100294 params.mStartedByNfc = intent.getBooleanExtra(EXTRA_PROVISIONING_STARTED_BY_NFC,
295 false);
Sander Alewijnsefd134872014-11-18 13:28:06 +0000296 params.mLeaveAllSystemAppsEnabled = intent.getBooleanExtra(
297 EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
298 ProvisioningParams.DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED);
Sander Alewijnse8f9bd132014-09-08 12:21:26 +0100299
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100300 try {
301 params.mAdminExtrasBundle = (PersistableBundle) intent.getParcelableExtra(
302 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
303 } catch (ClassCastException e) {
304 throw new ParseException("Extra " + EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
305 + " must be of type PersistableBundle.",
306 R.string.device_owner_error_general, e);
307 }
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100308
Sander Alewijnse56f71572014-06-23 16:21:33 +0100309 checkValidityOfProvisioningParams(params);
310 return params;
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000311 }
312
313 /**
Sander Alewijnse885c3492014-04-24 17:30:31 +0100314 * Check whether necessary fields are set.
315 */
316 private void checkValidityOfProvisioningParams(ProvisioningParams params)
317 throws ParseException {
Sander Alewijnsed7043852014-06-17 15:50:48 +0100318 if (TextUtils.isEmpty(params.mDeviceAdminPackageName)) {
Sander Alewijnse885c3492014-04-24 17:30:31 +0100319 throw new ParseException("Must provide the name of the device admin package.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100320 R.string.device_owner_error_general);
Sander Alewijnse885c3492014-04-24 17:30:31 +0100321 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100322 if (!TextUtils.isEmpty(params.mDeviceAdminPackageDownloadLocation)) {
323 if (params.mDeviceAdminPackageChecksum == null ||
324 params.mDeviceAdminPackageChecksum.length == 0) {
325 throw new ParseException("Checksum of installer file is required for downloading " +
Sander Alewijnse885c3492014-04-24 17:30:31 +0100326 "device admin file, but not provided.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100327 R.string.device_owner_error_general);
Sander Alewijnse885c3492014-04-24 17:30:31 +0100328 }
Sander Alewijnse885c3492014-04-24 17:30:31 +0100329 }
330 }
331
332 /**
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000333 * Exception thrown when the ProvisioningParams initialization failed completely.
334 *
335 * Note: We're using a custom exception to avoid catching subsequent exceptions that might be
336 * significant.
337 */
Sander Alewijnse885c3492014-04-24 17:30:31 +0100338 public static class ParseException extends Exception {
339 private int mErrorMessageId;
340
341 public ParseException(String message, int errorMessageId) {
342 super(message);
343 mErrorMessageId = errorMessageId;
344 }
345
346 public ParseException(String message, int errorMessageId, Throwable t) {
347 super(message, t);
348 mErrorMessageId = errorMessageId;
349 }
350
351 public int getErrorMessageId() {
352 return mErrorMessageId;
353 }
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000354 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100355
356 public static byte[] stringToByteArray(String s)
357 throws NumberFormatException {
Sander Alewijnse48fdbe02014-07-03 14:25:45 +0100358 try {
359 return Base64.decode(s, Base64.URL_SAFE);
360 } catch (IllegalArgumentException e) {
361 throw new NumberFormatException("Incorrect checksum format.");
Sander Alewijnse56f71572014-06-23 16:21:33 +0100362 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100363 }
364
365 public static Locale stringToLocale(String s)
Narayan Kamath53ff3c02014-07-17 14:02:58 +0100366 throws IllformedLocaleException {
367 return new Locale.Builder().setLanguageTag(s.replace("_", "-")).build();
Sander Alewijnse56f71572014-06-23 16:21:33 +0100368 }
Sander Alewijnse226d36c2014-06-26 16:33:05 +0000369}