blob: a1611f29881d18edff5fc8fa2b2d4bffbabcc2ef [file] [log] [blame]
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +01001/*
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
19import android.app.AlarmManager;
20import android.app.Service;
Craig Lafayettec25553f2015-03-28 17:00:52 -040021import android.app.admin.DeviceInitializerStatus;
Sander Alewijnseab18ea72014-09-11 15:15:23 +010022import android.content.BroadcastReceiver;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010023import android.content.ComponentName;
24import android.content.Context;
25import android.content.Intent;
Sander Alewijnseab18ea72014-09-11 15:15:23 +010026import android.content.pm.PackageManager;
Rubin Xu292e9a32015-03-20 17:02:38 +000027import android.os.Bundle;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010028import android.os.IBinder;
Nicolas Prevot3b76f0d2014-09-03 15:33:42 +010029import android.os.UserHandle;
Jessica Hummel81fe1042014-06-23 17:10:38 +010030import android.support.v4.content.LocalBroadcastManager;
Sander Alewijnse74d6c142015-04-13 11:51:19 +010031import android.text.TextUtils;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010032
33import com.android.internal.app.LocalePicker;
Sander Alewijnse74d6c142015-04-13 11:51:19 +010034import com.android.managedprovisioning.ProvisioningParams.PackageDownloadInfo;
Craig Lafayettec25553f2015-03-28 17:00:52 -040035import com.android.managedprovisioning.proxy.BluetoothConnectionService;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010036import com.android.managedprovisioning.task.AddWifiNetworkTask;
Craig Lafayettec25553f2015-03-28 17:00:52 -040037import com.android.managedprovisioning.task.BluetoothConnectTask;
Sander Alewijnse2818d322014-05-20 14:54:13 +010038import com.android.managedprovisioning.task.DeleteNonRequiredAppsTask;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010039import com.android.managedprovisioning.task.DownloadPackageTask;
40import com.android.managedprovisioning.task.InstallPackageTask;
41import com.android.managedprovisioning.task.SetDevicePolicyTask;
Craig Lafayette09928762015-03-29 20:48:07 -040042import com.android.managedprovisioning.task.WipeResetProtectionTask;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010043
44import java.lang.Runnable;
45import java.util.Locale;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010046
47/**
48 * This service does the work for the DeviceOwnerProvisioningActivity.
49 * Feedback is sent back to the activity via intents.
50 *
51 * <p>
52 * If the corresponding activity is killed and restarted, the service is
53 * called twice. The service will not start the provisioning flow a second time, but instead
54 * send a status update to the activity.
55 * </p>
56 */
57public class DeviceOwnerProvisioningService extends Service {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +000058 private static final boolean DEBUG = false; // To control logging.
59
Sander Alewijnse74d6c142015-04-13 11:51:19 +010060 private static final String DEVICE_OWNER = "deviceOwner";
61 private static final String DEVICE_INITIALIZER = "deviceInitializer";
62
Sander Alewijnse639e94c2014-05-01 16:07:51 +010063 /**
64 * Intent action to activate the CDMA phone connection by OTASP.
65 * This is not necessary for a GSM phone connection, which is activated automatically.
66 * String must agree with the constants in com.android.phone.InCallScreenShowActivation.
67 */
68 private static final String ACTION_PERFORM_CDMA_PROVISIONING =
69 "com.android.phone.PERFORM_CDMA_PROVISIONING";
70
Sander Alewijnse326bcfd2014-06-25 15:24:03 +010071 // Intent actions and extras for communication from DeviceOwnerProvisioningService to Activity.
72 protected static final String EXTRA_PROVISIONING_PARAMS =
73 "ProvisioningParams";
74
75 // Intent actions and extras for communication from DeviceOwnerProvisioningActivity to Service.
Sander Alewijnsed7043852014-06-17 15:50:48 +010076 protected static final String ACTION_PROVISIONING_SUCCESS =
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010077 "com.android.managedprovisioning.provisioning_success";
Sander Alewijnsed7043852014-06-17 15:50:48 +010078 protected static final String ACTION_PROVISIONING_ERROR =
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010079 "com.android.managedprovisioning.error";
Sander Alewijnsed7043852014-06-17 15:50:48 +010080 protected static final String EXTRA_USER_VISIBLE_ERROR_ID_KEY =
81 "UserVisibleErrorMessage-Id";
82 protected static final String ACTION_PROGRESS_UPDATE =
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010083 "com.android.managedprovisioning.progress_update";
Sander Alewijnsed7043852014-06-17 15:50:48 +010084 protected static final String EXTRA_PROGRESS_MESSAGE_ID_KEY =
85 "ProgressMessageId";
Sander Alewijnse326bcfd2014-06-25 15:24:03 +010086 protected static final String ACTION_REQUEST_WIFI_PICK =
87 "com.android.managedprovisioning.request_wifi_pick";
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010088
Sander Alewijnseab18ea72014-09-11 15:15:23 +010089 // Intent action used by the HomeReceiverActivity to notify this Service that a HOME intent was
90 // received, which indicates that the Setup wizard has closed after provisioning completed.
91 protected static final String ACTION_HOME_INDIRECT =
92 "com.android.managedprovisioning.home_indirect";
93
Sander Alewijnse326bcfd2014-06-25 15:24:03 +010094 // Indicates whether provisioning has started.
Sander Alewijnsed7043852014-06-17 15:50:48 +010095 private boolean mProvisioningInFlight = false;
Sander Alewijnse326bcfd2014-06-25 15:24:03 +010096
97 // MessageId of the last progress message.
Sander Alewijnsed7043852014-06-17 15:50:48 +010098 private int mLastProgressMessage = -1;
Sander Alewijnse326bcfd2014-06-25 15:24:03 +010099
100 // MessageId of the last error message.
Sander Alewijnsed7043852014-06-17 15:50:48 +0100101 private int mLastErrorMessage = -1;
Sander Alewijnse326bcfd2014-06-25 15:24:03 +0100102
Rubin Xu1662fa32015-03-18 12:44:28 +0000103 // Indicates whether provisioning has finished successfully (service waiting to stop).
104 private volatile boolean mDone = false;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100105
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100106 // Provisioning tasks.
Craig Lafayettec25553f2015-03-28 17:00:52 -0400107 private BluetoothConnectTask mBluetoothConnectTask;
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100108 private AddWifiNetworkTask mAddWifiNetworkTask;
Craig Lafayette09928762015-03-29 20:48:07 -0400109 private WipeResetProtectionTask mWipeResetProtectionTask;
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100110 private DownloadPackageTask mDownloadPackageTask;
111 private InstallPackageTask mInstallPackageTask;
112 private SetDevicePolicyTask mSetDevicePolicyTask;
113 private DeleteNonRequiredAppsTask mDeleteNonRequiredAppsTask;
114
Sander Alewijnsed7043852014-06-17 15:50:48 +0100115 private ProvisioningParams mParams;
116
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100117 @Override
118 public int onStartCommand(final Intent intent, int flags, int startId) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000119 if (DEBUG) ProvisionLogger.logd("Device owner provisioning service ONSTARTCOMMAND.");
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100120
Sander Alewijnsed7043852014-06-17 15:50:48 +0100121 synchronized (this) { // Make operations on mProvisioningInFlight atomic.
122 if (mProvisioningInFlight) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000123 if (DEBUG) ProvisionLogger.logd("Provisioning already in flight.");
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100124
Sander Alewijnsed7043852014-06-17 15:50:48 +0100125 sendProgressUpdateToActivity();
126
127 // Send error message if currently in error state.
128 if (mLastErrorMessage >= 0) {
129 sendError();
130 }
131
Rubin Xu1662fa32015-03-18 12:44:28 +0000132 // Send success if provisioning was successful.
Sander Alewijnsed7043852014-06-17 15:50:48 +0100133 if (mDone) {
Nicolas Prevot0b447252015-03-09 14:59:02 +0000134 onProvisioningSuccess();
Sander Alewijnsed7043852014-06-17 15:50:48 +0100135 }
136 } else {
137 mProvisioningInFlight = true;
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000138 if (DEBUG) ProvisionLogger.logd("First start of the service.");
Sander Alewijnsed7043852014-06-17 15:50:48 +0100139 progressUpdate(R.string.progress_data_process);
140
141 // Load the ProvisioningParams (from message in Intent).
142 mParams = (ProvisioningParams) intent.getParcelableExtra(EXTRA_PROVISIONING_PARAMS);
143
144 // Do the work on a separate thread.
145 new Thread(new Runnable() {
146 public void run() {
147 initializeProvisioningEnvironment(mParams);
148 startDeviceOwnerProvisioning(mParams);
149 }
150 }).start();
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100151 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100152 }
153 return START_NOT_STICKY;
154 }
155
156 /**
157 * This is the core method of this class. It goes through every provisioning step.
Julia Reynoldsccd60162015-02-17 11:53:48 -0500158 * Each task checks if it is required and executes if it is.
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100159 */
Sander Alewijnsee96a8202014-05-19 16:55:39 +0100160 private void startDeviceOwnerProvisioning(final ProvisioningParams params) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000161 if (DEBUG) ProvisionLogger.logd("Starting device owner provisioning");
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100162
163 // Construct Tasks. Do not start them yet.
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100164 mBluetoothConnectTask = new BluetoothConnectTask(this, params.bluetoothInfo,
165 !TextUtils.isEmpty(params.wifiInfo.ssid),
Craig Lafayettec25553f2015-03-28 17:00:52 -0400166 new BluetoothConnectTask.Callback() {
167 @Override
168 public void onSuccess() {
169 progressUpdate(R.string.progress_connect_to_wifi);
170 mAddWifiNetworkTask.run();
171 }
172 @Override
173 public void onError() {
174 error(R.string.device_owner_error_bluetooth);
175 }
176 });
177
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100178 mAddWifiNetworkTask = new AddWifiNetworkTask(this, params.wifiInfo,
179 new AddWifiNetworkTask.Callback() {
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500180 @Override
181 public void onSuccess() {
Craig Lafayette09928762015-03-29 20:48:07 -0400182 progressUpdate(R.string.progress_wipe_frp);
183 mWipeResetProtectionTask.run();
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500184 }
185
186 @Override
187 public void onError(){
188 error(R.string.device_owner_error_wifi);
Craig Lafayettec25553f2015-03-28 17:00:52 -0400189 statusUpdate(DeviceInitializerStatus.STATUS_ERROR_CONNECT_WIFI);
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500190 }
191 });
192
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100193 mWipeResetProtectionTask = new WipeResetProtectionTask(this, params.frpChallengeBundle,
Craig Lafayette09928762015-03-29 20:48:07 -0400194 new WipeResetProtectionTask.Callback() {
195 @Override
196 public void onSuccess() {
197 progressUpdate(R.string.progress_download);
198 mDownloadPackageTask.run();
199 }
200 @Override
201 public void onError() {
202 error(R.string.device_owner_error_frp);
Craig Lafayettec25553f2015-03-28 17:00:52 -0400203 statusUpdate(DeviceInitializerStatus.
204 STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING);
Craig Lafayette09928762015-03-29 20:48:07 -0400205 }
206 });
207
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100208 mDownloadPackageTask = new DownloadPackageTask(this,
209 new DownloadPackageTask.Callback() {
Julia Reynoldsccd60162015-02-17 11:53:48 -0500210 @Override
211 public void onSuccess() {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100212 progressUpdate(R.string.progress_install);
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100213 mInstallPackageTask.addInstallIfNecessary(
214 params.inferDeviceAdminPackageName(),
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500215 mDownloadPackageTask.getDownloadedPackageLocation(
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100216 DEVICE_OWNER));
217 mInstallPackageTask.addInstallIfNecessary(
218 params.getDeviceInitializerPackageName(),
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500219 mDownloadPackageTask.getDownloadedPackageLocation(
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100220 DEVICE_INITIALIZER));
221 mInstallPackageTask.run();
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100222 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100223
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100224 @Override
225 public void onError(int errorCode) {
226 switch(errorCode) {
227 case DownloadPackageTask.ERROR_HASH_MISMATCH:
228 error(R.string.device_owner_error_hash_mismatch);
229 break;
230 case DownloadPackageTask.ERROR_DOWNLOAD_FAILED:
231 error(R.string.device_owner_error_download_failed);
232 break;
233 default:
234 error(R.string.device_owner_error_general);
235 break;
236 }
Craig Lafayettec25553f2015-03-28 17:00:52 -0400237 statusUpdate(DeviceInitializerStatus.STATUS_ERROR_DOWNLOAD_PACKAGE);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100238 }
239 });
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100240
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100241 // Add packages to download to the DownloadPackageTask.
242 mDownloadPackageTask.addDownloadIfNecessary(params.inferDeviceAdminPackageName(),
243 params.deviceAdminDownloadInfo, DEVICE_OWNER);
244 mDownloadPackageTask.addDownloadIfNecessary(params.getDeviceInitializerPackageName(),
245 params.deviceInitializerDownloadInfo, DEVICE_INITIALIZER);
246
247 mInstallPackageTask = new InstallPackageTask(this,
248 new InstallPackageTask.Callback() {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100249 @Override
250 public void onSuccess() {
251 progressUpdate(R.string.progress_set_owner);
Nicolas Prevot668d65f2015-03-10 17:58:15 +0000252 try {
253 // Now that the app has been installed, we can look for the device admin
254 // component in it.
255 mSetDevicePolicyTask.run(mParams.inferDeviceAdminComponentName(
256 DeviceOwnerProvisioningService.this));
257 } catch (Utils.IllegalProvisioningArgumentException e) {
258 error(R.string.device_owner_error_general);
259 ProvisionLogger.loge("Failed to infer the device admin component name",
260 e);
261 return;
262 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100263 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100264
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100265 @Override
266 public void onError(int errorCode) {
267 switch(errorCode) {
268 case InstallPackageTask.ERROR_PACKAGE_INVALID:
269 error(R.string.device_owner_error_package_invalid);
270 break;
271 case InstallPackageTask.ERROR_INSTALLATION_FAILED:
272 error(R.string.device_owner_error_installation_failed);
273 break;
Joe Delfino84e56f52015-03-27 09:56:18 -0400274 case InstallPackageTask.ERROR_PACKAGE_NAME_INVALID:
275 error(R.string.device_owner_error_package_name_invalid);
276 break;
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100277 default:
278 error(R.string.device_owner_error_general);
279 break;
280 }
Craig Lafayettec25553f2015-03-28 17:00:52 -0400281 statusUpdate(DeviceInitializerStatus.STATUS_ERROR_INSTALL_PACKAGE);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100282 }
283 });
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100284
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100285 mSetDevicePolicyTask = new SetDevicePolicyTask(this,
Sander Alewijnse56f71572014-06-23 16:21:33 +0100286 getResources().getString(R.string.default_owned_device_username),
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100287 params.deviceInitializerComponentName,
Julia Reynolds3f4eb372015-02-11 13:46:42 -0500288 getResources().getString(R.string.default_owned_device_username),
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100289 new SetDevicePolicyTask.Callback() {
290 @Override
291 public void onSuccess() {
Julia Reynoldsccd60162015-02-17 11:53:48 -0500292 mDeleteNonRequiredAppsTask.run();
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100293 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100294
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100295 @Override
296 public void onError(int errorCode) {
297 switch(errorCode) {
298 case SetDevicePolicyTask.ERROR_PACKAGE_NOT_INSTALLED:
299 error(R.string.device_owner_error_package_not_installed);
300 break;
Sander Alewijnsecdf13b12014-06-19 15:58:15 +0100301 case SetDevicePolicyTask.ERROR_NO_RECEIVER:
Sander Alewijnseb6578e72014-07-25 17:12:05 +0100302 error(R.string.device_owner_error_package_invalid);
Sander Alewijnsecdf13b12014-06-19 15:58:15 +0100303 break;
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100304 default:
305 error(R.string.device_owner_error_general);
306 break;
307 }
Craig Lafayettec25553f2015-03-28 17:00:52 -0400308 statusUpdate(DeviceInitializerStatus.STATUS_ERROR_SET_DEVICE_POLICY);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100309 }
310 });
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100311
Nicolas Prevot3ebb7b02014-09-08 15:42:15 +0100312 mDeleteNonRequiredAppsTask = new DeleteNonRequiredAppsTask(
Nicolas Prevot668d65f2015-03-10 17:58:15 +0000313 this, params.inferDeviceAdminPackageName(), R.array.required_apps_managed_device,
Sander Alewijnsed5e4c422014-11-25 17:56:16 +0000314 R.array.vendor_required_apps_managed_device, true /* creating new profile */,
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100315 UserHandle.USER_OWNER, params.leaveAllSystemAppsEnabled,
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100316 new DeleteNonRequiredAppsTask.Callback() {
Rubin Xu1662fa32015-03-18 12:44:28 +0000317 @Override
Sander Alewijnse2818d322014-05-20 14:54:13 +0100318 public void onSuccess() {
319 // Done with provisioning. Success.
Nicolas Prevot0b447252015-03-09 14:59:02 +0000320 onProvisioningSuccess();
Sander Alewijnse2818d322014-05-20 14:54:13 +0100321 }
322
Jessica Hummel14eeef92014-06-16 11:06:20 +0100323 @Override
Sander Alewijnse2818d322014-05-20 14:54:13 +0100324 public void onError() {
325 error(R.string.device_owner_error_general);
Craig Lafayettec25553f2015-03-28 17:00:52 -0400326 statusUpdate(DeviceInitializerStatus.STATUS_ERROR_DELETE_APPS);
Rubin Xu1662fa32015-03-18 12:44:28 +0000327 }
Nicolas Prevot3ebb7b02014-09-08 15:42:15 +0100328 });
Sander Alewijnse2818d322014-05-20 14:54:13 +0100329
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100330 // Start first task, which starts next task in its callback, etc.
Craig Lafayettec25553f2015-03-28 17:00:52 -0400331 progressUpdate(R.string.progress_start_bluetooth);
332 mBluetoothConnectTask.run();
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100333 }
334
335 private void error(int dialogMessage) {
Sander Alewijnsed7043852014-06-17 15:50:48 +0100336 mLastErrorMessage = dialogMessage;
337 sendError();
338 // Wait for stopService() call from the activity.
339 }
Jessica Hummel14eeef92014-06-16 11:06:20 +0100340
Craig Lafayettec25553f2015-03-28 17:00:52 -0400341 private void statusUpdate(int statusCode) {
342 BluetoothConnectionService.sendStatusUpdate(this, statusCode);
343 }
344
Sander Alewijnsed7043852014-06-17 15:50:48 +0100345 private void sendError() {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000346 if (DEBUG) {
347 ProvisionLogger.logd("Reporting Error: " + getResources()
348 .getString(mLastErrorMessage));
349 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100350 Intent intent = new Intent(ACTION_PROVISIONING_ERROR);
Jessica Hummel14eeef92014-06-16 11:06:20 +0100351 intent.setClass(this, DeviceOwnerProvisioningActivity.ServiceMessageReceiver.class);
Sander Alewijnsed7043852014-06-17 15:50:48 +0100352 intent.putExtra(EXTRA_USER_VISIBLE_ERROR_ID_KEY, mLastErrorMessage);
Jessica Hummel81fe1042014-06-23 17:10:38 +0100353 LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100354 }
355
356 private void progressUpdate(int progressMessage) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000357 if (DEBUG) {
358 ProvisionLogger.logd("Reporting progress update: " + getResources()
359 .getString(progressMessage));
360 }
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100361 mLastProgressMessage = progressMessage;
362 sendProgressUpdateToActivity();
363 }
364
365 private void sendProgressUpdateToActivity() {
366 Intent intent = new Intent(ACTION_PROGRESS_UPDATE);
367 intent.putExtra(EXTRA_PROGRESS_MESSAGE_ID_KEY, mLastProgressMessage);
Jessica Hummel14eeef92014-06-16 11:06:20 +0100368 intent.setClass(this, DeviceOwnerProvisioningActivity.ServiceMessageReceiver.class);
Jessica Hummel81fe1042014-06-23 17:10:38 +0100369 LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100370 }
371
Nicolas Prevot0b447252015-03-09 14:59:02 +0000372 private void onProvisioningSuccess() {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000373 if (DEBUG) ProvisionLogger.logd("Reporting success.");
Sander Alewijnsed7043852014-06-17 15:50:48 +0100374 mDone = true;
Sander Alewijnseab18ea72014-09-11 15:15:23 +0100375
Rubin Xu292e9a32015-03-20 17:02:38 +0000376 // Persist mParams so HomeReceiverActivity can later retrieve them to finalize provisioning.
377 // This is necessary to deal with accidental reboots during DIA setup, which happens between
378 // the end of this method and HomeReceiverActivity captures the home intent.
379 IntentStore store = BootReminder.getDeviceOwnerFinalizingIntentStore(this);
380 Bundle resumeBundle = new Bundle();
381 (new MessageParser()).addProvisioningParamsToBundle(resumeBundle, mParams);
382 store.save(resumeBundle);
383
Sander Alewijnseab18ea72014-09-11 15:15:23 +0100384 // Enable the HomeReceiverActivity, since the DeviceOwnerProvisioningActivity will shutdown
385 // the Setup wizard soon, which will result in a home intent that should be caught by the
386 // HomeReceiverActivity.
387 PackageManager pm = getPackageManager();
388 pm.setComponentEnabledSetting(new ComponentName(DeviceOwnerProvisioningService.this,
389 HomeReceiverActivity.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
390 PackageManager.DONT_KILL_APP);
391
Jessica Hummel14eeef92014-06-16 11:06:20 +0100392 Intent successIntent = new Intent(ACTION_PROVISIONING_SUCCESS);
393 successIntent.setClass(this, DeviceOwnerProvisioningActivity.ServiceMessageReceiver.class);
Jessica Hummel81fe1042014-06-23 17:10:38 +0100394 LocalBroadcastManager.getInstance(this).sendBroadcast(successIntent);
Sander Alewijnsed7043852014-06-17 15:50:48 +0100395 // Wait for stopService() call from the activity.
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100396 }
397
398 private void initializeProvisioningEnvironment(ProvisioningParams params) {
Sander Alewijnse74d6c142015-04-13 11:51:19 +0100399 setTimeAndTimezone(params.timeZone, params.localTime);
400 setLocale(params.locale);
Sander Alewijnse639e94c2014-05-01 16:07:51 +0100401
402 // Start CDMA activation to enable phone calls.
403 final Intent intent = new Intent(ACTION_PERFORM_CDMA_PROVISIONING);
404 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000405 if (DEBUG) ProvisionLogger.logd("Starting cdma activation activity");
Sander Alewijnse639e94c2014-05-01 16:07:51 +0100406 startActivity(intent); // Activity will be a Nop if not a CDMA device.
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100407 }
408
Sander Alewijnsed7043852014-06-17 15:50:48 +0100409 private void setTimeAndTimezone(String timeZone, long localTime) {
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100410 try {
411 final AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
412 if (timeZone != null) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000413 if (DEBUG) ProvisionLogger.logd("Setting time zone to " + timeZone);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100414 am.setTimeZone(timeZone);
415 }
Sander Alewijnsed7043852014-06-17 15:50:48 +0100416 if (localTime > 0) {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000417 if (DEBUG) ProvisionLogger.logd("Setting time to " + localTime);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100418 am.setTime(localTime);
419 }
420 } catch (Exception e) {
421 ProvisionLogger.loge("Alarm manager failed to set the system time/timezone.");
422 // Do not stop provisioning process, but ignore this error.
423 }
424 }
425
426 private void setLocale(Locale locale) {
427 if (locale == null || locale.equals(Locale.getDefault())) {
428 return;
429 }
430 try {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000431 if (DEBUG) ProvisionLogger.logd("Setting locale to " + locale);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100432 // If locale is different from current locale this results in a configuration change,
433 // which will trigger the restarting of the activity.
434 LocalePicker.updateLocale(locale);
435 } catch (Exception e) {
436 ProvisionLogger.loge("Failed to set the system locale.");
437 // Do not stop provisioning process, but ignore this error.
438 }
439 }
440
441 @Override
Sander Alewijnsed7043852014-06-17 15:50:48 +0100442 public void onCreate () {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000443 if (DEBUG) ProvisionLogger.logd("Device owner provisioning service ONCREATE.");
Sander Alewijnsed7043852014-06-17 15:50:48 +0100444 }
445
446 @Override
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100447 public void onDestroy () {
Sander Alewijnse9a40ab02014-10-27 18:36:56 +0000448 if (DEBUG) ProvisionLogger.logd("Device owner provisioning service ONDESTROY");
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100449 if (mAddWifiNetworkTask != null) {
Sander Alewijnsed7043852014-06-17 15:50:48 +0100450 mAddWifiNetworkTask.cleanUp();
451 }
452 if (mDownloadPackageTask != null) {
453 mDownloadPackageTask.cleanUp();
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100454 }
Craig Lafayette85582cf2015-04-14 22:57:33 -0400455 if (mBluetoothConnectTask != null) {
456 mBluetoothConnectTask.cleanUp();
457 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100458 }
459
460 @Override
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100461 public IBinder onBind(Intent intent) {
462 return null;
463 }
464}
465