blob: 23f55b9abec4390d1a49a4458659a68be5659b31 [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
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.app.admin.DevicePolicyManager;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010022import android.content.BroadcastReceiver;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000023import android.content.Context;
24import android.content.DialogInterface;
25import android.content.Intent;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010026import android.content.IntentFilter;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000027import android.os.Bundle;
28import android.provider.Settings.Global;
Jessica Hummel81fe1042014-06-23 17:10:38 +010029import android.support.v4.content.LocalBroadcastManager;
Sander Alewijnseed0883b2014-03-18 15:01:13 +000030import android.view.LayoutInflater;
31import android.view.View;
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010032import android.widget.TextView;
Sander Alewijnsec7757382014-03-18 17:09:45 +000033
Sander Alewijnseed0883b2014-03-18 15:01:13 +000034/**
35 * This activity starts device owner provisioning:
36 * It downloads a mobile device management application(mdm) from a given url and installs it,
37 * or a given mdm is already present on the device. The mdm is set as the owner of the device so
38 * that it has full control over the device:
39 * TODO: put link here with documentation on how a device owner has control over the device
40 * The mdm can then execute further setup steps.
41 *
42 * <p>
43 * An example use case might be when a company wants to set up a device for a single use case
44 * (such as giving instructions).
45 * </p>
46 *
47 * <p>
48 * Provisioning is triggered by a programmer device that sends required provisioning parameters via
49 * nfc. For an example of a programmer app see:
50 * com.example.android.apis.app.DeviceProvisioningProgrammerSample.
51 * </p>
52 *
Sander Alewijnse4c4badf2014-03-20 14:12:49 +000053 * <p>
54 * In the unlikely case that this activity is killed the whole provisioning process so far is
55 * repeated. We made sure that all tasks can be done twice without causing any problems.
56 * </p>
Sander Alewijnseed0883b2014-03-18 15:01:13 +000057 */
58public class DeviceOwnerProvisioningActivity extends Activity {
Sander Alewijnse28bffd62014-06-05 10:54:26 +010059 private static final int ENCRYPT_DEVICE_REQUEST_CODE = 1;
60
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010061 private BroadcastReceiver mServiceMessageReceiver;
62 private TextView mProgressTextView;
63
Sander Alewijnseed0883b2014-03-18 15:01:13 +000064 @Override
65 public void onCreate(Bundle savedInstanceState) {
66 super.onCreate(savedInstanceState);
67
68 ProvisionLogger.logd("Device owner provisioning activity ONCREATE");
69
70 // Check whether we can provision.
71 if (Global.getInt(getContentResolver(), Global.DEVICE_PROVISIONED, /* default */ 0) != 0) {
72 ProvisionLogger.loge("Device already provisioned.");
73 error(R.string.device_owner_error_already_provisioned);
74 return;
75 }
76
77 DevicePolicyManager dpm = (DevicePolicyManager)
78 getSystemService(Context.DEVICE_POLICY_SERVICE);
79 if (dpm.getDeviceOwner() != null) {
80 ProvisionLogger.loge("Device owner already present.");
81 error(R.string.device_owner_error_already_owned);
82 return;
83 }
84
Sander Alewijnseed0883b2014-03-18 15:01:13 +000085 final LayoutInflater inflater = getLayoutInflater();
Sander Alewijnse8ce0c512014-06-03 17:49:02 +010086 final View contentView = inflater.inflate(R.layout.progress, null);
Sander Alewijnseed0883b2014-03-18 15:01:13 +000087 setContentView(contentView);
Sander Alewijnse8ce0c512014-06-03 17:49:02 +010088 mProgressTextView = (TextView) findViewById(R.id.prog_text);
Sander Alewijnseed0883b2014-03-18 15:01:13 +000089
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010090 // Setup broadcast receiver for feedback from service.
91 mServiceMessageReceiver = new ServiceMessageReceiver();
92 IntentFilter filter = new IntentFilter();
93 filter.addAction(DeviceOwnerProvisioningService.ACTION_PROVISIONING_SUCCESS);
94 filter.addAction(DeviceOwnerProvisioningService.ACTION_PROVISIONING_ERROR);
95 filter.addAction(DeviceOwnerProvisioningService.ACTION_PROGRESS_UPDATE);
Sander Alewijnse28bffd62014-06-05 10:54:26 +010096 filter.addAction(DeviceOwnerProvisioningService.ACTION_REQUEST_ENCRYPTION);
Jessica Hummel81fe1042014-06-23 17:10:38 +010097 LocalBroadcastManager.getInstance(this).registerReceiver(mServiceMessageReceiver, filter);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +010098
99 // Start service.
100 Intent intent = new Intent(this, DeviceOwnerProvisioningService.class);
101 intent.putExtras(getIntent());
102 startService(intent);
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000103 }
104
Jessica Hummel14eeef92014-06-16 11:06:20 +0100105 class ServiceMessageReceiver extends BroadcastReceiver
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100106 {
107 @Override
108 public void onReceive(Context context, Intent intent)
109 {
110 String action = intent.getAction();
111 if (action.equals(DeviceOwnerProvisioningService.ACTION_PROVISIONING_SUCCESS)) {
112 ProvisionLogger.logd("Successfully provisioned");
113 finish();
114 return;
115 } else if (action.equals(DeviceOwnerProvisioningService.ACTION_PROVISIONING_ERROR)) {
116 int errorCode = intent.getIntExtra(
Jessica Hummel14eeef92014-06-16 11:06:20 +0100117 DeviceOwnerProvisioningService.EXTRA_USER_VISIBLE_ERROR_ID_KEY, -1);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100118 ProvisionLogger.logd("Error reported with code "
119 + getResources().getString(errorCode));
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100120 if (errorCode < 0) {
121 error(R.string.device_owner_error_general);
122 return;
Sander Alewijnseaf8413e2014-03-19 11:37:44 +0000123 } else {
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100124 error(errorCode);
125 }
126 } else if (action.equals(DeviceOwnerProvisioningService.ACTION_PROGRESS_UPDATE)) {
127 int progressMessage = intent.getIntExtra(
128 DeviceOwnerProvisioningService.EXTRA_PROGRESS_MESSAGE_ID_KEY, -1);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100129 ProvisionLogger.logd("Progress update reported with code "
130 + getResources().getString(progressMessage));
131 if (progressMessage >= 0) {
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100132 progressUpdate(progressMessage);
Sander Alewijnseaf8413e2014-03-19 11:37:44 +0000133 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100134 } else if (action.equals(DeviceOwnerProvisioningService.ACTION_REQUEST_ENCRYPTION)) {
135 ProvisionLogger.logd("Received request to encrypt device.");
136 Intent encryptIntent = new Intent(DeviceOwnerProvisioningActivity.this,
137 EncryptDeviceActivity.class);
138 encryptIntent.putExtras(intent);
139 startActivityForResult(encryptIntent, ENCRYPT_DEVICE_REQUEST_CODE);
Sander Alewijnsec7757382014-03-18 17:09:45 +0000140 }
Sander Alewijnse63254f42014-03-21 15:31:12 +0000141 }
142 }
143
144 @Override
145 public void onBackPressed() {
146 // TODO: Handle this graciously by stopping the provisioning flow and cleaning up.
147 }
148
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100149 @Override
150 public void onDestroy() {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100151 ProvisionLogger.logd("Device owner provisioning activity ONDESTROY");
Jessica Hummel81fe1042014-06-23 17:10:38 +0100152 LocalBroadcastManager.getInstance(this).unregisterReceiver(mServiceMessageReceiver);
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100153 super.onDestroy();
154 }
155
156 private void progressUpdate(int progressMessage) {
157 mProgressTextView.setText(progressMessage);
158 }
159
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100160 @Override
161 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
162 if (requestCode == ENCRYPT_DEVICE_REQUEST_CODE) {
163 if (resultCode == RESULT_CANCELED) {
164 ProvisionLogger.loge("User canceled device encryption.");
165 finish();
166 }
167 }
168 }
169
Sander Alewijnse04ab6fe2014-04-29 10:53:54 +0100170 private void error(int dialogMessage) {
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000171 AlertDialog dlg = new AlertDialog.Builder(this)
172 .setTitle(R.string.device_owner_error_title)
173 .setMessage(dialogMessage)
174 .setCancelable(false)
175 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
Jessica Hummel14eeef92014-06-16 11:06:20 +0100176 @Override
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000177 public void onClick(DialogInterface dialog,int id) {
178 // Close activity
179 finish();
180 }
181 })
182 .create();
183 dlg.show();
184 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100185
Jessica Hummel14eeef92014-06-16 11:06:20 +0100186 @Override
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100187 protected void onRestart() {
188 ProvisionLogger.logd("Device owner provisioning activity ONRESTART");
189 super.onRestart();
190 }
191
Jessica Hummel14eeef92014-06-16 11:06:20 +0100192 @Override
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100193 protected void onResume() {
194 ProvisionLogger.logd("Device owner provisioning activity ONRESUME");
195 super.onResume();
196 }
197
Jessica Hummel14eeef92014-06-16 11:06:20 +0100198 @Override
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100199 protected void onPause() {
200 ProvisionLogger.logd("Device owner provisioning activity ONPAUSE");
201 super.onPause();
202 }
203
Jessica Hummel14eeef92014-06-16 11:06:20 +0100204 @Override
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100205 protected void onStop() {
206 ProvisionLogger.logd("Device owner provisioning activity ONSTOP");
207 super.onStop();
208 }
Sander Alewijnseed0883b2014-03-18 15:01:13 +0000209}
210