blob: e611bdbb3ca125d57c2088e6419f1113081da6ea [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 Alewijnse9aff1402014-07-18 17:15:32 +010030import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
Sander Alewijnse56f71572014-06-23 16:21:33 +010031import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +010032import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER;
Sander Alewijnse56f71572014-06-23 16:21:33 +010033import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
Sander Alewijnseae9b8212014-07-18 17:25:53 +010034import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_EMAIL_ADDRESS;
Sander Alewijnse56f71572014-06-23 16:21:33 +010035import static android.app.admin.DevicePolicyManager.PROVISIONING_NFC_MIME_TYPE;
Sander Alewijnse28bffd62014-06-05 10:54:26 +010036import static java.nio.charset.StandardCharsets.UTF_8;
37
Sander Alewijnseed0883b2014-03-18 15:01:13 +000038import android.content.Intent;
39import android.nfc.NdefMessage;
40import android.nfc.NdefRecord;
41import android.nfc.NfcAdapter;
Sander Alewijnse9aff1402014-07-18 17:15:32 +010042import android.os.Bundle;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000043import android.os.Parcelable;
Sander Alewijnsed7043852014-06-17 15:50:48 +010044import android.text.TextUtils;
Sander Alewijnse48fdbe02014-07-03 14:25:45 +010045import android.util.Base64;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000046
47import java.io.IOException;
48import java.io.StringReader;
49import java.util.Enumeration;
50import java.util.HashMap;
Narayan Kamath53ff3c02014-07-17 14:02:58 +010051import java.util.IllformedLocaleException;
Sander Alewijnse63254f42014-03-21 15:31:12 +000052import java.util.Locale;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000053import java.util.Properties;
54
55/**
56 * This class can initialize a ProvisioningParams object from an intent.
Sander Alewijnse56f71572014-06-23 16:21:33 +010057 * There are two kinds of intents that can be parsed.
Sander Alewijnse28bffd62014-06-05 10:54:26 +010058 *
59 * <p>
Sander Alewijnse56f71572014-06-23 16:21:33 +010060 * Intent was received via Nfc.
61 * The intent contains the extra {@link NfcAdapter.EXTRA_NDEF_MESSAGES}, which indicates that
62 * provisioning was started via Nfc bump. This extra contains an NDEF message, which contains an
63 * NfcRecord with mime type {@link PROVISIONING_NFC_MIME_TYPE}. This record stores a serialized
64 * properties object, which contains the serialized extra's described in the next option.
65 * A typical use case would be a programmer application that sends an Nfc bump to start Nfc
66 * provisioning from a programmer device.
Sander Alewijnse28bffd62014-06-05 10:54:26 +010067 *
68 * <p>
Sander Alewijnse56f71572014-06-23 16:21:33 +010069 * Intent was received directly.
70 * The intent contains the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME},
71 * and may contain {@link #EXTRA_PROVISIONING_TIME_ZONE},
72 * {@link #EXTRA_PROVISIONING_LOCAL_TIME}, and {@link #EXTRA_PROVISIONING_LOCALE}. A download
73 * location may be specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +010074 * together with an optional http cookie header
75 * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER} accompanied by the SHA-1
76 * sum of the target file {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}.
77 * Furthermore a wifi network may be specified in {@link #EXTRA_PROVISIONING_WIFI_SSID}, and if
78 * applicable {@link #EXTRA_PROVISIONING_WIFI_HIDDEN},
79 * {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE}, {@link #EXTRA_PROVISIONING_WIFI_PASSWORD},
80 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, {@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT},
81 * {@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}.
Sander Alewijnse56f71572014-06-23 16:21:33 +010082 * A typical use case would be the {@link BootReminder} sending the intent after device encryption
83 * and reboot.
Sander Alewijnse9aff1402014-07-18 17:15:32 +010084 *
85 * <p>
86 * Furthermore this class can construct the bundle of extras for the second kind of intent, and it
87 * keeps track of the types of the extras in the DEVICE_OWNER_x_EXTRAS, with x the appropriate type.
Sander Alewijnseed0883b2014-03-18 15:01:13 +000088 */
Sander Alewijnse28bffd62014-06-05 10:54:26 +010089public class MessageParser {
Sander Alewijnse9aff1402014-07-18 17:15:32 +010090 protected static final String[] DEVICE_OWNER_STRING_EXTRAS = {
91 EXTRA_PROVISIONING_TIME_ZONE,
92 EXTRA_PROVISIONING_LOCALE,
93 EXTRA_PROVISIONING_WIFI_SSID,
94 EXTRA_PROVISIONING_WIFI_SECURITY_TYPE,
95 EXTRA_PROVISIONING_WIFI_PASSWORD,
96 EXTRA_PROVISIONING_WIFI_PROXY_HOST,
97 EXTRA_PROVISIONING_WIFI_PROXY_BYPASS,
98 EXTRA_PROVISIONING_WIFI_PAC_URL,
99 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
100 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100101 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
Sander Alewijnseae9b8212014-07-18 17:25:53 +0100102 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
103 EXTRA_PROVISIONING_EMAIL_ADDRESS
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100104 };
105
106 protected static final String[] DEVICE_OWNER_LONG_EXTRAS = {
107 EXTRA_PROVISIONING_LOCAL_TIME
108 };
109
110 protected static final String[] DEVICE_OWNER_INT_EXTRAS = {
111 EXTRA_PROVISIONING_WIFI_PROXY_PORT
112 };
113
114 protected static final String[] DEVICE_OWNER_BOOLEAN_EXTRAS = {
115 EXTRA_PROVISIONING_WIFI_HIDDEN
116 };
117
118 public void addProvisioningParamsToBundle(Bundle bundle, ProvisioningParams params) {
119 bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, params.mTimeZone);
120 bundle.putString(EXTRA_PROVISIONING_LOCALE, params.getLocaleAsString());
121 bundle.putString(EXTRA_PROVISIONING_WIFI_SSID, params.mWifiSsid);
122 bundle.putString(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, params.mWifiSecurityType);
123 bundle.putString(EXTRA_PROVISIONING_WIFI_PASSWORD, params.mWifiPassword);
124 bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_HOST, params.mWifiProxyHost);
125 bundle.putString(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS, params.mWifiProxyBypassHosts);
126 bundle.putString(EXTRA_PROVISIONING_WIFI_PAC_URL, params.mWifiPacUrl);
127 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
128 params.mDeviceAdminPackageName);
129 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
130 params.mDeviceAdminPackageDownloadLocation);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100131 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER,
132 params.mDeviceAdminPackageDownloadCookieHeader);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100133 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
134 params.getDeviceAdminPackageChecksumAsString());
Sander Alewijnseae9b8212014-07-18 17:25:53 +0100135 bundle.putString(EXTRA_PROVISIONING_EMAIL_ADDRESS, params.mManagedDeviceEmailAddress);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100136
137 bundle.putLong(EXTRA_PROVISIONING_LOCAL_TIME, params.mLocalTime);
138
139 bundle.putInt(EXTRA_PROVISIONING_WIFI_PROXY_PORT, params.mWifiProxyPort);
140
141 bundle.putBoolean(EXTRA_PROVISIONING_WIFI_HIDDEN, params.mWifiHidden);
142 }
143
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100144 public ProvisioningParams parseIntent(Intent intent) throws ParseException {
145 ProvisionLogger.logi("Processing intent.");
146 if (intent.hasExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
147 return parseNfcIntent(intent);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000148 } else {
Sander Alewijnse56f71572014-06-23 16:21:33 +0100149 return parseNonNfcIntent(intent);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000150 }
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000151 }
152
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100153 public ProvisioningParams parseNfcIntent(Intent nfcIntent)
154 throws ParseException {
155 ProvisionLogger.logi("Processing Nfc Payload.");
156 // Only one first message with NFC_MIME_TYPE is used.
157 for (Parcelable rawMsg : nfcIntent
158 .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
159 NdefMessage msg = (NdefMessage) rawMsg;
160
161 // Assume only first record of message is used.
162 NdefRecord firstRecord = msg.getRecords()[0];
163 String mimeType = new String(firstRecord.getType(), UTF_8);
164
Sander Alewijnse56f71572014-06-23 16:21:33 +0100165 if (PROVISIONING_NFC_MIME_TYPE.equals(mimeType)) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100166 return parseProperties(new String(firstRecord.getPayload(), UTF_8));
167 }
168 }
169 throw new ParseException(
170 "Intent does not contain NfcRecord with the correct MIME type.",
Bill Yi125bf212014-07-28 10:54:17 -0700171 R.string.device_owner_error_general);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100172 }
173
174 private ProvisioningParams parseProperties(String data)
Sander Alewijnse885c3492014-04-24 17:30:31 +0100175 throws ParseException {
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000176 ProvisioningParams params = new ProvisioningParams();
177 try {
178 Properties props = new Properties();
179 props.load(new StringReader(data));
180
Sander Alewijnse56f71572014-06-23 16:21:33 +0100181 String s; // Used for parsing non-Strings.
Sander Alewijnse56f71572014-06-23 16:21:33 +0100182 params.mTimeZone
183 = props.getProperty(EXTRA_PROVISIONING_TIME_ZONE);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100184 if ((s = props.getProperty(EXTRA_PROVISIONING_LOCALE)) != null) {
185 params.mLocale = stringToLocale(s);
186 }
187 params.mWifiSsid = props.getProperty(EXTRA_PROVISIONING_WIFI_SSID);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100188 params.mWifiSecurityType = props.getProperty(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
189 params.mWifiPassword = props.getProperty(EXTRA_PROVISIONING_WIFI_PASSWORD);
190 params.mWifiProxyHost = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100191 params.mWifiProxyBypassHosts = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
192 params.mWifiPacUrl = props.getProperty(EXTRA_PROVISIONING_WIFI_PAC_URL);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100193 params.mDeviceAdminPackageName
194 = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100195 params.mDeviceAdminPackageDownloadLocation
196 = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100197 params.mDeviceAdminPackageDownloadCookieHeader = props.getProperty(
198 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100199 if ((s = props.getProperty(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM)) != null) {
200 params.mDeviceAdminPackageChecksum = stringToByteArray(s);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000201 }
Sander Alewijnseae9b8212014-07-18 17:25:53 +0100202 params.mManagedDeviceEmailAddress = props.getProperty(EXTRA_PROVISIONING_EMAIL_ADDRESS);
Sander Alewijnse885c3492014-04-24 17:30:31 +0100203
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100204 if ((s = props.getProperty(EXTRA_PROVISIONING_LOCAL_TIME)) != null) {
205 params.mLocalTime = Long.parseLong(s);
206 }
207
208 if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_PROXY_PORT)) != null) {
209 params.mWifiProxyPort = Integer.parseInt(s);
210 }
211
212 if ((s = props.getProperty(EXTRA_PROVISIONING_WIFI_HIDDEN)) != null) {
213 params.mWifiHidden = Boolean.parseBoolean(s);
214 }
215
Sander Alewijnse885c3492014-04-24 17:30:31 +0100216 checkValidityOfProvisioningParams(params);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000217 return params;
218 } catch (IOException e) {
Sander Alewijnse885c3492014-04-24 17:30:31 +0100219 throw new ParseException("Couldn't load payload",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100220 R.string.device_owner_error_general, e);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000221 } catch (NumberFormatException e) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100222 throw new ParseException("Incorrect numberformat.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100223 R.string.device_owner_error_general, e);
Narayan Kamath53ff3c02014-07-17 14:02:58 +0100224 } catch (IllformedLocaleException e) {
225 throw new ParseException("Invalid locale.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100226 R.string.device_owner_error_general, e);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000227 }
228 }
229
Sander Alewijnse56f71572014-06-23 16:21:33 +0100230 public ProvisioningParams parseNonNfcIntent(Intent intent)
231 throws ParseException {
232 ProvisionLogger.logi("Processing intent.");
233 ProvisioningParams params = new ProvisioningParams();
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000234
Sander Alewijnse56f71572014-06-23 16:21:33 +0100235 params.mTimeZone = intent.getStringExtra(EXTRA_PROVISIONING_TIME_ZONE);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100236 String localeString = intent.getStringExtra(EXTRA_PROVISIONING_LOCALE);
237 if (localeString != null) {
238 params.mLocale = stringToLocale(localeString);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000239 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100240 params.mWifiSsid = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SSID);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100241 params.mWifiSecurityType = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE);
242 params.mWifiPassword = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PASSWORD);
243 params.mWifiProxyHost = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_HOST);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100244 params.mWifiProxyBypassHosts = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PROXY_BYPASS);
245 params.mWifiPacUrl = intent.getStringExtra(EXTRA_PROVISIONING_WIFI_PAC_URL);
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100246 params.mDeviceAdminPackageName
247 = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100248 params.mDeviceAdminPackageDownloadLocation
249 = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION);
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100250 params.mDeviceAdminPackageDownloadCookieHeader = intent.getStringExtra(
251 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100252 String hashString = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM);
253 if (hashString != null) {
254 params.mDeviceAdminPackageChecksum = stringToByteArray(hashString);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000255 }
Sander Alewijnseae9b8212014-07-18 17:25:53 +0100256 params.mManagedDeviceEmailAddress
257 = intent.getStringExtra(EXTRA_PROVISIONING_EMAIL_ADDRESS);
Sander Alewijnse56f71572014-06-23 16:21:33 +0100258
Sander Alewijnse9aff1402014-07-18 17:15:32 +0100259 params.mLocalTime = intent.getLongExtra(EXTRA_PROVISIONING_LOCAL_TIME,
260 ProvisioningParams.DEFAULT_LOCAL_TIME);
261
262 params.mWifiProxyPort = intent.getIntExtra(EXTRA_PROVISIONING_WIFI_PROXY_PORT,
263 ProvisioningParams.DEFAULT_WIFI_PROXY_PORT);
264
265 params.mWifiHidden = intent.getBooleanExtra(EXTRA_PROVISIONING_WIFI_HIDDEN,
266 ProvisioningParams.DEFAULT_WIFI_HIDDEN);
267
Sander Alewijnse56f71572014-06-23 16:21:33 +0100268 checkValidityOfProvisioningParams(params);
269 return params;
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000270 }
271
272 /**
Sander Alewijnse885c3492014-04-24 17:30:31 +0100273 * Check whether necessary fields are set.
274 */
275 private void checkValidityOfProvisioningParams(ProvisioningParams params)
276 throws ParseException {
Sander Alewijnsed7043852014-06-17 15:50:48 +0100277 if (TextUtils.isEmpty(params.mDeviceAdminPackageName)) {
Sander Alewijnse885c3492014-04-24 17:30:31 +0100278 throw new ParseException("Must provide the name of the device admin package.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100279 R.string.device_owner_error_general);
Sander Alewijnse885c3492014-04-24 17:30:31 +0100280 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100281 if (!TextUtils.isEmpty(params.mDeviceAdminPackageDownloadLocation)) {
282 if (params.mDeviceAdminPackageChecksum == null ||
283 params.mDeviceAdminPackageChecksum.length == 0) {
284 throw new ParseException("Checksum of installer file is required for downloading " +
Sander Alewijnse885c3492014-04-24 17:30:31 +0100285 "device admin file, but not provided.",
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100286 R.string.device_owner_error_general);
Sander Alewijnse885c3492014-04-24 17:30:31 +0100287 }
Sander Alewijnse885c3492014-04-24 17:30:31 +0100288 }
289 }
290
291 /**
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000292 * Exception thrown when the ProvisioningParams initialization failed completely.
293 *
294 * Note: We're using a custom exception to avoid catching subsequent exceptions that might be
295 * significant.
296 */
Sander Alewijnse885c3492014-04-24 17:30:31 +0100297 public static class ParseException extends Exception {
298 private int mErrorMessageId;
299
300 public ParseException(String message, int errorMessageId) {
301 super(message);
302 mErrorMessageId = errorMessageId;
303 }
304
305 public ParseException(String message, int errorMessageId, Throwable t) {
306 super(message, t);
307 mErrorMessageId = errorMessageId;
308 }
309
310 public int getErrorMessageId() {
311 return mErrorMessageId;
312 }
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000313 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100314
315 public static byte[] stringToByteArray(String s)
316 throws NumberFormatException {
Sander Alewijnse48fdbe02014-07-03 14:25:45 +0100317 try {
318 return Base64.decode(s, Base64.URL_SAFE);
319 } catch (IllegalArgumentException e) {
320 throw new NumberFormatException("Incorrect checksum format.");
Sander Alewijnse56f71572014-06-23 16:21:33 +0100321 }
Sander Alewijnse56f71572014-06-23 16:21:33 +0100322 }
323
324 public static Locale stringToLocale(String s)
Narayan Kamath53ff3c02014-07-17 14:02:58 +0100325 throws IllformedLocaleException {
326 return new Locale.Builder().setLanguageTag(s.replace("_", "-")).build();
Sander Alewijnse56f71572014-06-23 16:21:33 +0100327 }
Sander Alewijnse226d36c2014-06-26 16:33:05 +0000328}