1 /* 2 * Copyright (C) 2016 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.internal.app; 18 19 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; 20 21 import android.accounts.Account; 22 import android.accounts.AccountManager; 23 import android.content.DialogInterface; 24 import android.content.Intent; 25 import android.content.pm.ApplicationInfo; 26 import android.content.pm.PackageInfo; 27 import android.content.pm.PackageManager.NameNotFoundException; 28 import android.content.pm.UserInfo; 29 import android.os.Bundle; 30 import android.os.PersistableBundle; 31 import android.os.UserHandle; 32 import android.os.UserManager; 33 import android.util.Log; 34 35 import com.android.internal.R; 36 37 /** 38 * Activity to confirm with the user that it is ok to create a new user, as requested by 39 * an app. It has to do some checks to decide what kind of prompt the user should be shown. 40 * Particularly, it needs to check if the account requested already exists on another user. 41 */ 42 public class ConfirmUserCreationActivity extends AlertActivity 43 implements DialogInterface.OnClickListener { 44 45 private static final String TAG = "CreateUser"; 46 47 private String mUserName; 48 private String mAccountName; 49 private String mAccountType; 50 private PersistableBundle mAccountOptions; 51 private boolean mCanProceed; 52 private UserManager mUserManager; 53 54 @Override onCreate(Bundle icicle)55 public void onCreate(Bundle icicle) { 56 super.onCreate(icicle); 57 58 getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); 59 60 Intent intent = getIntent(); 61 mUserName = intent.getStringExtra(UserManager.EXTRA_USER_NAME); 62 mAccountName = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_NAME); 63 mAccountType = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_TYPE); 64 mAccountOptions = (PersistableBundle) 65 intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS); 66 67 mUserManager = getSystemService(UserManager.class); 68 69 String message = checkUserCreationRequirements(); 70 71 if (message == null) { 72 finish(); 73 return; 74 } 75 final AlertController.AlertParams ap = mAlertParams; 76 ap.mMessage = message; 77 ap.mPositiveButtonText = getString(android.R.string.ok); 78 ap.mPositiveButtonListener = this; 79 80 // Show the negative button if the user actually has a choice 81 if (mCanProceed) { 82 ap.mNegativeButtonText = getString(android.R.string.cancel); 83 ap.mNegativeButtonListener = this; 84 } 85 setupAlert(); 86 } 87 checkUserCreationRequirements()88 private String checkUserCreationRequirements() { 89 final String callingPackage = getCallingPackage(); 90 if (callingPackage == null) { 91 throw new SecurityException( 92 "User Creation intent must be launched with startActivityForResult"); 93 } 94 final ApplicationInfo appInfo; 95 try { 96 appInfo = getPackageManager().getApplicationInfo(callingPackage, 0); 97 } catch (NameNotFoundException nnfe) { 98 throw new SecurityException( 99 "Cannot find the calling package"); 100 } 101 final String message; 102 // Check the user restrictions 103 boolean cantCreateUser = mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER) 104 || !mUserManager.isAdminUser(); 105 // Check the system state and user count 106 boolean cantCreateAnyMoreUsers = !mUserManager.canAddMoreUsers(); 107 // Check the account existence 108 final Account account = new Account(mAccountName, mAccountType); 109 boolean accountExists = mAccountName != null && mAccountType != null 110 && (AccountManager.get(this).someUserHasAccount(account) 111 | mUserManager.someUserHasSeedAccount(mAccountName, mAccountType)); 112 mCanProceed = true; 113 final String appName = appInfo.loadLabel(getPackageManager()).toString(); 114 if (cantCreateUser) { 115 setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED); 116 return null; 117 } else if (cantCreateAnyMoreUsers) { 118 setResult(UserManager.USER_CREATION_FAILED_NO_MORE_USERS); 119 return null; 120 } else if (accountExists) { 121 message = getString(R.string.user_creation_account_exists, appName, mAccountName); 122 } else { 123 message = getString(R.string.user_creation_adding, appName, mAccountName); 124 } 125 return message; 126 } 127 128 @Override onClick(DialogInterface dialog, int which)129 public void onClick(DialogInterface dialog, int which) { 130 setResult(RESULT_CANCELED); 131 if (which == BUTTON_POSITIVE && mCanProceed) { 132 Log.i(TAG, "Ok, creating user"); 133 UserInfo user = mUserManager.createUser(mUserName, 0); 134 if (user == null) { 135 Log.e(TAG, "Couldn't create user"); 136 finish(); 137 return; 138 } 139 mUserManager.setSeedAccountData(user.id, mAccountName, mAccountType, mAccountOptions); 140 setResult(RESULT_OK); 141 } 142 finish(); 143 } 144 } 145