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