160 lines
6.5 KiB
Java
160 lines
6.5 KiB
Java
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.internal.app;
|
|
|
|
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
|
|
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.content.pm.ApplicationInfo;
|
|
import android.content.pm.PackageManager.NameNotFoundException;
|
|
import android.content.pm.UserInfo;
|
|
import android.os.Bundle;
|
|
import android.os.PersistableBundle;
|
|
import android.os.UserManager;
|
|
import android.util.Log;
|
|
|
|
import com.android.internal.R;
|
|
|
|
/**
|
|
* Activity to confirm with the user that it is ok to create a new user, as requested by
|
|
* an app. It has to do some checks to decide what kind of prompt the user should be shown.
|
|
* Particularly, it needs to check if the account requested already exists on another user.
|
|
*/
|
|
public class ConfirmUserCreationActivity extends AlertActivity
|
|
implements DialogInterface.OnClickListener {
|
|
|
|
private static final String TAG = "CreateUser";
|
|
|
|
private static final String USER_TYPE = UserManager.USER_TYPE_FULL_SECONDARY;
|
|
|
|
private String mUserName;
|
|
private String mAccountName;
|
|
private String mAccountType;
|
|
private PersistableBundle mAccountOptions;
|
|
private boolean mCanProceed;
|
|
private boolean mIsFirstClick;
|
|
private UserManager mUserManager;
|
|
|
|
@Override
|
|
public void onCreate(Bundle icicle) {
|
|
super.onCreate(icicle);
|
|
|
|
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
|
|
|
Intent intent = getIntent();
|
|
mUserName = intent.getStringExtra(UserManager.EXTRA_USER_NAME);
|
|
mAccountName = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_NAME);
|
|
mAccountType = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_TYPE);
|
|
mAccountOptions = (PersistableBundle)
|
|
intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS, android.os.PersistableBundle.class);
|
|
|
|
mUserManager = getSystemService(UserManager.class);
|
|
|
|
String message = checkUserCreationRequirements();
|
|
|
|
if (message == null) {
|
|
finish();
|
|
return;
|
|
}
|
|
final AlertController.AlertParams ap = mAlertParams;
|
|
ap.mMessage = message;
|
|
ap.mPositiveButtonText = getString(android.R.string.ok);
|
|
ap.mPositiveButtonListener = this;
|
|
|
|
// Show the negative button if the user actually has a choice
|
|
if (mCanProceed) {
|
|
ap.mNegativeButtonText = getString(android.R.string.cancel);
|
|
ap.mNegativeButtonListener = this;
|
|
}
|
|
mIsFirstClick = true;
|
|
setupAlert();
|
|
}
|
|
|
|
private String checkUserCreationRequirements() {
|
|
final String callingPackage = getCallingPackage();
|
|
if (callingPackage == null) {
|
|
throw new SecurityException(
|
|
"User Creation intent must be launched with startActivityForResult");
|
|
}
|
|
final ApplicationInfo appInfo;
|
|
try {
|
|
appInfo = getPackageManager().getApplicationInfo(callingPackage, 0);
|
|
} catch (NameNotFoundException nnfe) {
|
|
throw new SecurityException(
|
|
"Cannot find the calling package");
|
|
}
|
|
final String message;
|
|
// Check the user restrictions
|
|
boolean cantCreateUser = mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)
|
|
|| !mUserManager.isAdminUser();
|
|
// Check the system state and user count
|
|
boolean cantCreateAnyMoreUsers = !mUserManager.canAddMoreUsers(USER_TYPE);
|
|
// Check the account existence
|
|
final Account account = new Account(mAccountName, mAccountType);
|
|
boolean accountExists = mAccountName != null && mAccountType != null
|
|
&& (AccountManager.get(this).someUserHasAccount(account)
|
|
| mUserManager.someUserHasSeedAccount(mAccountName, mAccountType));
|
|
mCanProceed = true;
|
|
final String appName = appInfo.loadLabel(getPackageManager()).toString();
|
|
if (cantCreateUser) {
|
|
setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED);
|
|
return null;
|
|
} else if (!(isUserPropertyWithinLimit(mUserName, UserManager.MAX_USER_NAME_LENGTH)
|
|
&& isUserPropertyWithinLimit(mAccountName, UserManager.MAX_ACCOUNT_STRING_LENGTH)
|
|
&& isUserPropertyWithinLimit(mAccountType, UserManager.MAX_ACCOUNT_STRING_LENGTH))
|
|
|| (mAccountOptions != null && !mAccountOptions.isBundleContentsWithinLengthLimit(
|
|
UserManager.MAX_ACCOUNT_OPTIONS_LENGTH))) {
|
|
setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED);
|
|
Log.i(TAG, "User properties must not exceed their character limits");
|
|
return null;
|
|
} else if (cantCreateAnyMoreUsers) {
|
|
setResult(UserManager.USER_CREATION_FAILED_NO_MORE_USERS);
|
|
return null;
|
|
} else if (accountExists) {
|
|
message = getString(R.string.user_creation_account_exists, appName, mAccountName);
|
|
} else {
|
|
message = getString(R.string.user_creation_adding, appName, mAccountName);
|
|
}
|
|
return message;
|
|
}
|
|
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
setResult(RESULT_CANCELED);
|
|
if (which == BUTTON_POSITIVE && mCanProceed && mIsFirstClick) {
|
|
mIsFirstClick = false;
|
|
Log.i(TAG, "Ok, creating user");
|
|
UserInfo user = mUserManager.createUser(mUserName, USER_TYPE, 0);
|
|
if (user == null) {
|
|
Log.e(TAG, "Couldn't create user");
|
|
finish();
|
|
return;
|
|
}
|
|
mUserManager.setSeedAccountData(user.id, mAccountName, mAccountType, mAccountOptions);
|
|
setResult(RESULT_OK);
|
|
}
|
|
finish();
|
|
}
|
|
|
|
private boolean isUserPropertyWithinLimit(String property, int limit) {
|
|
return property == null || property.length() <= limit;
|
|
}
|
|
}
|