Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 1 | /* |
| 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 | |
| 17 | package com.android.managedprovisioning; |
| 18 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 19 | import android.app.Activity; |
| 20 | import android.app.AlertDialog; |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 21 | import android.app.admin.DevicePolicyManager; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 22 | import android.content.ComponentName; |
| 23 | import android.content.Context; |
| 24 | import android.content.DialogInterface; |
| 25 | import android.content.Intent; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 26 | import android.content.pm.ApplicationInfo; |
| 27 | import android.content.pm.PackageManager; |
| 28 | import android.content.pm.ResolveInfo; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 29 | import android.content.pm.UserInfo; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 30 | import android.os.Build; |
| 31 | import android.os.Bundle; |
| 32 | import android.os.PersistableBundle; |
| 33 | import android.os.Process; |
| 34 | import android.os.SystemProperties; |
| 35 | import android.os.UserHandle; |
| 36 | import android.os.UserManager; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 37 | import android.view.LayoutInflater; |
| 38 | import android.view.View; |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 39 | import android.widget.Button; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 40 | import android.widget.ImageView; |
| 41 | import android.widget.TextView; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 42 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 43 | import com.android.managedprovisioning.DeleteManagedProfileDialog.DeleteManagedProfileCallback; |
| 44 | import com.android.managedprovisioning.UserConsentDialog.ConsentCallback; |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 45 | import com.android.managedprovisioning.Utils.IllegalProvisioningArgumentException; |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 46 | import com.android.managedprovisioning.Utils.MdmPackageInfo; |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 47 | import com.android.setupwizard.navigationbar.SetupWizardNavBar; |
| 48 | import com.android.setupwizard.navigationbar.SetupWizardNavBar.NavigationBarListener; |
| 49 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 50 | import java.util.List; |
| 51 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 52 | import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; |
| 53 | import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME; |
| 54 | import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME; |
| 55 | import static com.android.managedprovisioning.EncryptDeviceActivity.EXTRA_RESUME_TARGET; |
| 56 | import static com.android.managedprovisioning.EncryptDeviceActivity.TARGET_PROFILE_OWNER; |
| 57 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 58 | /** |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 59 | * The activity sets up the environment in which the {@link ProfileOwnerProvisioningActivity} can be run. |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 60 | * It makes sure the device is encrypted, the current launcher supports managed profiles, the |
| 61 | * provisioning intent extras are valid, and that the already present managed profile is removed. |
| 62 | */ |
| 63 | public class ProfileOwnerPreProvisioningActivity extends Activity |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 64 | implements ConsentCallback, DeleteManagedProfileCallback, NavigationBarListener { |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 65 | |
| 66 | private static final String MANAGE_USERS_PERMISSION = "android.permission.MANAGE_USERS"; |
| 67 | |
| 68 | // Note: must match the constant defined in HomeSettings |
| 69 | private static final String EXTRA_SUPPORT_MANAGED_PROFILES = "support_managed_profiles"; |
| 70 | |
| 71 | // Aliases to start profile owner provisioning with and without MANAGE_USERS permission |
| 72 | protected static final ComponentName ALIAS_CHECK_CALLER = |
| 73 | new ComponentName("com.android.managedprovisioning", |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 74 | "com.android.managedprovisioning.ProfileOwnerProvisioningActivity"); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 75 | |
| 76 | protected static final ComponentName ALIAS_NO_CHECK_CALLER = |
| 77 | new ComponentName("com.android.managedprovisioning", |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 78 | "com.android.managedprovisioning.ProfileOwnerProvisioningActivityNoCallerCheck"); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 79 | |
| 80 | protected static final int PROVISIONING_REQUEST_CODE = 3; |
| 81 | protected static final int ENCRYPT_DEVICE_REQUEST_CODE = 2; |
| 82 | protected static final int CHANGE_LAUNCHER_REQUEST_CODE = 1; |
| 83 | |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 84 | // Hide default system navigation bar. |
| 85 | protected static final int IMMERSIVE_FLAGS = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
| 86 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; |
| 87 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 88 | private String mMdmPackageName; |
| 89 | |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 90 | private ComponentName mMdmComponentName; |
| 91 | |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 92 | private Button mSetupButton; |
| 93 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 94 | private DeleteManagedProfileDialog mDeleteDialog; |
| 95 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 96 | @Override |
| 97 | protected void onCreate(Bundle savedInstanceState) { |
| 98 | super.onCreate(savedInstanceState); |
| 99 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 100 | final LayoutInflater inflater = getLayoutInflater(); |
| 101 | View contentView = inflater.inflate(R.layout.user_consent, null); |
| 102 | setContentView(contentView); |
| 103 | |
Sander Alewijnse | a36dd99 | 2015-01-15 16:41:43 +0000 | [diff] [blame] | 104 | TextView titleView = (TextView) findViewById(R.id.title); |
| 105 | if (titleView != null) titleView.setText(getString(R.string.setup_work_profile)); |
| 106 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 107 | // Check whether system has the required managed profile feature. |
| 108 | if (!systemHasManagedProfileFeature()) { |
| 109 | showErrorAndClose(R.string.managed_provisioning_not_supported, |
| 110 | "Exiting managed profile provisioning, " |
| 111 | + "managed profiles feature is not available"); |
| 112 | return; |
| 113 | } |
| 114 | if (Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER) { |
| 115 | showErrorAndClose(R.string.user_is_not_owner, |
| 116 | "Exiting managed profile provisioning, calling user is not owner."); |
| 117 | return; |
| 118 | } |
Joe Delfino | 6079da1 | 2015-04-10 13:08:15 -0400 | [diff] [blame] | 119 | if (Utils.hasDeviceOwner(this)) { |
| 120 | showErrorAndClose(R.string.device_owner_exists, |
| 121 | "Exiting managed profile provisioning, a device owner exists"); |
| 122 | } |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 123 | |
| 124 | // Initialize member variables from the intent, stop if the intent wasn't valid. |
| 125 | try { |
| 126 | initialize(getIntent()); |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 127 | } catch (IllegalProvisioningArgumentException e) { |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 128 | showErrorAndClose(R.string.managed_provisioning_error_text, e.getMessage()); |
| 129 | return; |
| 130 | } |
| 131 | |
| 132 | setMdmIcon(mMdmPackageName); |
| 133 | |
| 134 | // If the caller started us via ALIAS_NO_CHECK_CALLER then they must have permission to |
| 135 | // MANAGE_USERS since it is a restricted intent. Otherwise, check the calling package. |
| 136 | boolean hasManageUsersPermission = (getComponentName().equals(ALIAS_NO_CHECK_CALLER)); |
| 137 | if (!hasManageUsersPermission) { |
| 138 | // Calling package has to equal the requested device admin package or has to be system. |
| 139 | String callingPackage = getCallingPackage(); |
| 140 | if (callingPackage == null) { |
| 141 | showErrorAndClose(R.string.managed_provisioning_error_text, |
| 142 | "Calling package is null. " + |
| 143 | "Was startActivityForResult used to start this activity?"); |
| 144 | return; |
| 145 | } |
| 146 | if (!callingPackage.equals(mMdmPackageName) |
| 147 | && !packageHasManageUsersPermission(callingPackage)) { |
| 148 | showErrorAndClose(R.string.managed_provisioning_error_text, "Permission denied, " |
| 149 | + "calling package tried to set a different package as profile owner. " |
| 150 | + "The system MANAGE_USERS permission is required."); |
| 151 | return; |
| 152 | } |
| 153 | } |
| 154 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 155 | // If there is already a managed profile, setup the profile deletion dialog. |
Sudheer Shanka | 5b77487 | 2015-01-22 12:00:33 +0000 | [diff] [blame] | 156 | // Otherwise, check whether system has reached maximum user limit. |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 157 | int existingManagedProfileUserId = alreadyHasManagedProfile(); |
| 158 | if (existingManagedProfileUserId != -1) { |
Joe Delfino | 6079da1 | 2015-04-10 13:08:15 -0400 | [diff] [blame] | 159 | DevicePolicyManager dpm = |
| 160 | (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 161 | createDeleteManagedProfileDialog(dpm, existingManagedProfileUserId); |
Sudheer Shanka | 5b77487 | 2015-01-22 12:00:33 +0000 | [diff] [blame] | 162 | } else if (isMaximumUserLimitReached()) { |
| 163 | showErrorAndClose(R.string.maximum_user_limit_reached, |
| 164 | "Exiting managed profile provisioning, cannot add more users."); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 165 | } else { |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 166 | showStartProvisioningButton(); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 167 | } |
| 168 | } |
| 169 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 170 | @Override |
| 171 | protected void onResume() { |
| 172 | super.onResume(); |
| 173 | |
| 174 | if (alreadyHasManagedProfile() != -1) { |
| 175 | showDeleteManagedProfileDialog(); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | @Override |
| 180 | protected void onPause() { |
| 181 | super.onPause(); |
| 182 | |
| 183 | hideDeleteManagedProfileDialog(); |
| 184 | } |
| 185 | |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 186 | private void showStartProvisioningButton() { |
| 187 | mSetupButton.setVisibility(View.VISIBLE); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | private boolean packageHasManageUsersPermission(String pkg) { |
| 191 | return PackageManager.PERMISSION_GRANTED == getPackageManager() |
| 192 | .checkPermission(MANAGE_USERS_PERMISSION, pkg); |
| 193 | } |
| 194 | |
| 195 | private boolean systemHasManagedProfileFeature() { |
| 196 | PackageManager pm = getPackageManager(); |
| 197 | return pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS); |
| 198 | } |
| 199 | |
Sudheer Shanka | 5b77487 | 2015-01-22 12:00:33 +0000 | [diff] [blame] | 200 | private boolean isMaximumUserLimitReached() { |
| 201 | UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); |
| 202 | return !userManager.canAddMoreUsers(); |
| 203 | } |
| 204 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 205 | private boolean currentLauncherSupportsManagedProfiles() { |
| 206 | Intent intent = new Intent(Intent.ACTION_MAIN); |
| 207 | intent.addCategory(Intent.CATEGORY_HOME); |
| 208 | |
| 209 | PackageManager pm = getPackageManager(); |
| 210 | ResolveInfo launcherResolveInfo |
| 211 | = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); |
Nicolas Prevot | 849d267 | 2014-12-09 16:25:42 +0000 | [diff] [blame] | 212 | if (launcherResolveInfo == null) { |
| 213 | return false; |
| 214 | } |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 215 | try { |
Sudheer Shanka | a33d2d4 | 2015-02-03 21:05:16 +0000 | [diff] [blame] | 216 | // If the user has not chosen a default launcher, then launcherResolveInfo will be |
| 217 | // referring to the resolver activity. It is fine to create a managed profile in |
| 218 | // this case since there will always be at least one launcher on the device that |
| 219 | // supports managed profile feature. |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 220 | ApplicationInfo launcherAppInfo = getPackageManager().getApplicationInfo( |
| 221 | launcherResolveInfo.activityInfo.packageName, 0 /* default flags */); |
| 222 | return versionNumberAtLeastL(launcherAppInfo.targetSdkVersion); |
| 223 | } catch (PackageManager.NameNotFoundException e) { |
| 224 | return false; |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | private boolean versionNumberAtLeastL(int versionNumber) { |
| 229 | return versionNumber >= Build.VERSION_CODES.LOLLIPOP; |
| 230 | } |
| 231 | |
| 232 | private void setMdmIcon(String packageName) { |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 233 | MdmPackageInfo packageInfo = Utils.getMdmPackageInfo(getPackageManager(), packageName); |
| 234 | if (packageInfo != null) { |
| 235 | ImageView imageView = (ImageView) findViewById(R.id.mdm_icon_view); |
| 236 | imageView.setImageDrawable(packageInfo.getPackageIcon()); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 237 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 238 | TextView deviceManagerName = (TextView) findViewById(R.id.device_manager_name); |
| 239 | deviceManagerName.setText(packageInfo.getAppLabel()); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 240 | } |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * Checks if all required provisioning parameters are provided. |
| 245 | * Does not check for extras that are optional such as wifi ssid. |
| 246 | * Also checks whether type of admin extras bundle (if present) is PersistableBundle. |
| 247 | * |
| 248 | * @param intent The intent that started provisioning |
| 249 | */ |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 250 | private void initialize(Intent intent) throws IllegalProvisioningArgumentException { |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 251 | // Check if the admin extras bundle is of the right type. |
| 252 | try { |
| 253 | PersistableBundle bundle = (PersistableBundle) getIntent().getParcelableExtra( |
| 254 | EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE); |
| 255 | } catch (ClassCastException e) { |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 256 | throw new IllegalProvisioningArgumentException("Extra " |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 257 | + EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE |
| 258 | + " must be of type PersistableBundle.", e); |
| 259 | } |
| 260 | |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 261 | mMdmComponentName = Utils.findDeviceAdminFromIntent(intent, this); |
| 262 | mMdmPackageName = mMdmComponentName.getPackageName(); |
| 263 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 264 | } |
| 265 | |
| 266 | /** |
| 267 | * If the device is encrypted start the service which does the provisioning, otherwise ask for |
| 268 | * user consent to encrypt the device. |
| 269 | */ |
| 270 | private void checkEncryptedAndStartProvisioningService() { |
| 271 | if (EncryptDeviceActivity.isDeviceEncrypted() |
| 272 | || SystemProperties.getBoolean("persist.sys.no_req_encrypt", false)) { |
| 273 | |
| 274 | // Notify the user once more that the admin will have full control over the profile, |
| 275 | // then start provisioning. |
| 276 | UserConsentDialog.newInstance(UserConsentDialog.PROFILE_OWNER) |
| 277 | .show(getFragmentManager(), "UserConsentDialogFragment"); |
| 278 | } else { |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 279 | Bundle resumeExtras = getNewExtras(); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 280 | resumeExtras.putString(EXTRA_RESUME_TARGET, TARGET_PROFILE_OWNER); |
| 281 | Intent encryptIntent = new Intent(this, EncryptDeviceActivity.class) |
| 282 | .putExtra(EXTRA_RESUME, resumeExtras); |
| 283 | startActivityForResult(encryptIntent, ENCRYPT_DEVICE_REQUEST_CODE); |
| 284 | // Continue in onActivityResult or after reboot. |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | @Override |
| 289 | public void onDialogConsent() { |
| 290 | setupEnvironmentAndProvision(); |
| 291 | } |
| 292 | |
| 293 | @Override |
| 294 | public void onDialogCancel() { |
| 295 | // Do nothing. |
| 296 | } |
| 297 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 298 | @Override |
| 299 | public void onRemoveProfileApproval(int existingManagedProfileUserId) { |
| 300 | mDeleteDialog = null; |
| 301 | UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); |
| 302 | userManager.removeUser(existingManagedProfileUserId); |
| 303 | showStartProvisioningButton(); |
| 304 | } |
| 305 | |
| 306 | @Override |
| 307 | public void onRemoveProfileCancel() { |
| 308 | finish(); |
| 309 | } |
| 310 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 311 | private void setupEnvironmentAndProvision() { |
| 312 | // Remove any pre-provisioning UI in favour of progress display |
| 313 | BootReminder.cancelProvisioningReminder(this); |
| 314 | |
| 315 | // Check whether the current launcher supports managed profiles. |
| 316 | if (!currentLauncherSupportsManagedProfiles()) { |
| 317 | showCurrentLauncherInvalid(); |
| 318 | } else { |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 319 | startProfileOwnerProvisioning(); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 320 | } |
| 321 | } |
| 322 | |
| 323 | private void pickLauncher() { |
| 324 | Intent changeLauncherIntent = new Intent("android.settings.HOME_SETTINGS"); |
| 325 | changeLauncherIntent.putExtra(EXTRA_SUPPORT_MANAGED_PROFILES, true); |
| 326 | startActivityForResult(changeLauncherIntent, CHANGE_LAUNCHER_REQUEST_CODE); |
| 327 | // Continue in onActivityResult. |
| 328 | } |
| 329 | |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 330 | private void startProfileOwnerProvisioning() { |
| 331 | Intent intent = new Intent(this, ProfileOwnerProvisioningActivity.class); |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 332 | intent.putExtras(getNewExtras()); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 333 | startActivityForResult(intent, PROVISIONING_REQUEST_CODE); |
Rubin Xu | 5be74c5 | 2014-12-17 11:42:02 +0000 | [diff] [blame] | 334 | // Set cross-fade transition animation into the interstitial progress activity. |
| 335 | overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 336 | } |
| 337 | |
Nicolas Prevot | 0b44725 | 2015-03-09 14:59:02 +0000 | [diff] [blame] | 338 | private Bundle getNewExtras() { |
| 339 | Bundle bundle = getIntent().getExtras(); |
| 340 | // The original intent may have contained the package name but not the component name. |
| 341 | // But now, we know what the component name is. So let's pass it. |
| 342 | bundle.putParcelable(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, |
| 343 | mMdmComponentName); |
| 344 | return bundle; |
| 345 | } |
| 346 | |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 347 | @Override |
| 348 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
| 349 | if (requestCode == ENCRYPT_DEVICE_REQUEST_CODE) { |
| 350 | if (resultCode == RESULT_CANCELED) { |
| 351 | ProvisionLogger.loge("User canceled device encryption."); |
| 352 | setResult(Activity.RESULT_CANCELED); |
| 353 | finish(); |
| 354 | } |
| 355 | } else if (requestCode == CHANGE_LAUNCHER_REQUEST_CODE) { |
| 356 | if (resultCode == RESULT_CANCELED) { |
| 357 | showCurrentLauncherInvalid(); |
| 358 | } else if (resultCode == RESULT_OK) { |
Sander Alewijnse | 30bc13c | 2014-11-03 12:21:30 +0000 | [diff] [blame] | 359 | startProfileOwnerProvisioning(); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 360 | } |
| 361 | } |
| 362 | if (requestCode == PROVISIONING_REQUEST_CODE) { |
| 363 | setResult(resultCode); |
| 364 | finish(); |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | private void showCurrentLauncherInvalid() { |
| 369 | new AlertDialog.Builder(this) |
| 370 | .setCancelable(false) |
| 371 | .setMessage(R.string.managed_provisioning_not_supported_by_launcher) |
| 372 | .setNegativeButton(R.string.cancel_provisioning, |
| 373 | new DialogInterface.OnClickListener() { |
| 374 | @Override |
| 375 | public void onClick(DialogInterface dialog,int id) { |
| 376 | dialog.dismiss(); |
| 377 | setResult(Activity.RESULT_CANCELED); |
| 378 | finish(); |
| 379 | } |
| 380 | }) |
| 381 | .setPositiveButton(R.string.pick_launcher, |
| 382 | new DialogInterface.OnClickListener() { |
| 383 | @Override |
| 384 | public void onClick(DialogInterface dialog,int id) { |
| 385 | pickLauncher(); |
| 386 | } |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 387 | }) |
| 388 | .show() |
| 389 | .getWindow().getDecorView().setSystemUiVisibility(IMMERSIVE_FLAGS); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 390 | } |
| 391 | |
| 392 | public void showErrorAndClose(int resourceId, String logText) { |
| 393 | ProvisionLogger.loge(logText); |
| 394 | new AlertDialog.Builder(this) |
| 395 | .setTitle(R.string.provisioning_error_title) |
| 396 | .setMessage(getString(resourceId)) |
| 397 | .setCancelable(false) |
| 398 | .setPositiveButton(R.string.device_owner_error_ok, new DialogInterface.OnClickListener() { |
| 399 | @Override |
| 400 | public void onClick(DialogInterface dialog,int id) { |
| 401 | // Close activity |
| 402 | ProfileOwnerPreProvisioningActivity.this |
| 403 | .setResult(Activity.RESULT_CANCELED); |
| 404 | ProfileOwnerPreProvisioningActivity.this.finish(); |
| 405 | } |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 406 | }) |
| 407 | .show() |
| 408 | .getWindow().getDecorView().setSystemUiVisibility(IMMERSIVE_FLAGS); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 409 | } |
| 410 | |
| 411 | /** |
| 412 | * @return The User id of an already existing managed profile or -1 if none |
| 413 | * exists |
| 414 | */ |
| 415 | int alreadyHasManagedProfile() { |
| 416 | UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); |
| 417 | List<UserInfo> profiles = userManager.getProfiles(getUserId()); |
| 418 | for (UserInfo userInfo : profiles) { |
| 419 | if (userInfo.isManagedProfile()) { |
| 420 | return userInfo.getUserHandle().getIdentifier(); |
| 421 | } |
| 422 | } |
| 423 | return -1; |
| 424 | } |
| 425 | |
| 426 | /** |
Alan Treadway | d1050f1 | 2015-02-20 16:47:36 +0000 | [diff] [blame] | 427 | * Builds a dialog that allows the user to remove an existing managed profile. |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 428 | */ |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 429 | private void createDeleteManagedProfileDialog(DevicePolicyManager dpm, |
| 430 | int existingManagedProfileUserId) { |
| 431 | if (mDeleteDialog != null) { |
| 432 | return; |
| 433 | } |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 434 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 435 | ComponentName mdmPackageName = dpm.getProfileOwnerAsUser(existingManagedProfileUserId); |
| 436 | String domainName = dpm.getProfileOwnerNameAsUser(existingManagedProfileUserId); |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 437 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 438 | mDeleteDialog = DeleteManagedProfileDialog.newInstance(existingManagedProfileUserId, |
| 439 | mdmPackageName, domainName); |
| 440 | } |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 441 | |
Alan Treadway | 9a42f2b | 2015-02-25 15:12:31 +0000 | [diff] [blame] | 442 | private void showDeleteManagedProfileDialog() { |
| 443 | if (mDeleteDialog == null) { |
| 444 | return; |
| 445 | } |
| 446 | |
| 447 | if (!mDeleteDialog.isVisible()) { |
| 448 | mDeleteDialog.show(getFragmentManager(), "DeleteManagedProfileDialogFragment"); |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | private void hideDeleteManagedProfileDialog() { |
| 453 | if (mDeleteDialog == null) { |
| 454 | return; |
| 455 | } |
| 456 | |
| 457 | mDeleteDialog.dismiss(); |
| 458 | mDeleteDialog = null; |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 459 | } |
Alan Treadway | d1050f1 | 2015-02-20 16:47:36 +0000 | [diff] [blame] | 460 | |
Rubin Xu | 44cdbdf | 2014-11-28 15:19:14 +0000 | [diff] [blame] | 461 | @Override |
| 462 | public void onNavigationBarCreated(SetupWizardNavBar bar) { |
| 463 | mSetupButton = bar.getNextButton(); |
| 464 | mSetupButton.setText(R.string.set_up); |
| 465 | mSetupButton.setVisibility(View.INVISIBLE); |
| 466 | } |
| 467 | |
| 468 | @Override |
| 469 | public void onNavigateBack() { |
| 470 | onBackPressed(); |
| 471 | } |
| 472 | |
| 473 | @Override |
| 474 | public void onNavigateNext() { |
| 475 | checkEncryptedAndStartProvisioningService(); |
| 476 | } |
Sander Alewijnse | 606780d | 2014-10-29 10:51:39 +0000 | [diff] [blame] | 477 | } |
| 478 | |