Merge "Revert "Improve multi user settings screen"" into rvc-dev am: e13919cf4b
Change-Id: I7e067881864b96e067d2b763dc41d6b3680750df
This commit is contained in:
@@ -97,15 +97,8 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
/** Key for extra passed in from calling fragment to indicate if this is a newly created user */
|
||||
public static final String EXTRA_NEW_USER = "new_user";
|
||||
|
||||
/**
|
||||
* Key for extra passed in from calling fragment to indicate if
|
||||
* switch to user should be shown
|
||||
*/
|
||||
public static final String EXTRA_SHOW_SWITCH_USER = "enable_switch";
|
||||
|
||||
private boolean mFirstTime = true;
|
||||
private boolean mNewUser;
|
||||
protected boolean mShowSwitchUser;
|
||||
private boolean mAppListChanged;
|
||||
protected boolean mRestrictedProfile;
|
||||
|
||||
@@ -226,7 +219,6 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
mUser = new UserHandle(args.getInt(EXTRA_USER_ID));
|
||||
}
|
||||
mNewUser = args.getBoolean(EXTRA_NEW_USER, false);
|
||||
mShowSwitchUser = args.getBoolean(EXTRA_SHOW_SWITCH_USER, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.users;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.DialogInterface;
|
||||
@@ -24,10 +23,7 @@ import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
@@ -40,7 +36,6 @@ import com.android.settingslib.utils.ThreadUtils;
|
||||
public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
implements EditUserInfoController.OnContentChangedCallback {
|
||||
|
||||
private static final String TAG = RestrictedProfileSettings.class.getSimpleName();
|
||||
public static final String FILE_PROVIDER_AUTHORITY = "com.android.settings.files";
|
||||
static final int DIALOG_ID_EDIT_USER_INFO = 1;
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 2;
|
||||
@@ -49,8 +44,6 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
private ImageView mUserIconView;
|
||||
private TextView mUserNameView;
|
||||
private ImageView mDeleteButton;
|
||||
private View mSwitchUserView;
|
||||
private TextView mSwitchTitle;
|
||||
|
||||
private EditUserInfoController mEditUserInfoController =
|
||||
new EditUserInfoController();
|
||||
@@ -74,11 +67,6 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
mUserNameView = (TextView) mHeaderView.findViewById(android.R.id.title);
|
||||
mDeleteButton = (ImageView) mHeaderView.findViewById(R.id.delete);
|
||||
mDeleteButton.setOnClickListener(this);
|
||||
|
||||
mSwitchTitle = mHeaderView.findViewById(R.id.switchTitle);
|
||||
mSwitchUserView = mHeaderView.findViewById(R.id.switch_pref);
|
||||
mSwitchUserView.setOnClickListener(v -> switchUser());
|
||||
|
||||
// This is going to bind the preferences.
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
@@ -92,6 +80,7 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// Check if user still exists
|
||||
UserInfo info = Utils.getExistingUser(mUserManager, mUser);
|
||||
if (info == null) {
|
||||
@@ -100,16 +89,6 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
((TextView) mHeaderView.findViewById(android.R.id.title)).setText(info.name);
|
||||
((ImageView) mHeaderView.findViewById(android.R.id.icon)).setImageDrawable(
|
||||
com.android.settingslib.Utils.getUserIcon(getActivity(), mUserManager, info));
|
||||
|
||||
boolean canSwitchUser =
|
||||
mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK;
|
||||
if (mShowSwitchUser && canSwitchUser) {
|
||||
mSwitchUserView.setVisibility(View.VISIBLE);
|
||||
mSwitchTitle.setText(getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
info.name));
|
||||
} else {
|
||||
mSwitchUserView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,16 +158,6 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
});
|
||||
}
|
||||
|
||||
private void switchUser() {
|
||||
try {
|
||||
ActivityManager.getService().switchUser(mUser.getIdentifier());
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Error while switching to other user.");
|
||||
} finally {
|
||||
finishFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhotoChanged(UserHandle user, Drawable photo) {
|
||||
mUserIconView.setImageDrawable(photo);
|
||||
|
@@ -16,63 +16,55 @@
|
||||
|
||||
package com.android.settings.users;
|
||||
|
||||
import static android.os.UserHandle.USER_NULL;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Settings screen for configuring, deleting or switching to a specific user.
|
||||
* It is shown when you tap on a user in the user management (UserSettings) screen.
|
||||
* Settings screen for configuring a specific user. It can contain user restrictions
|
||||
* and deletion controls. It is shown when you tap on the settings icon in the
|
||||
* user management (UserSettings) screen.
|
||||
*
|
||||
* Arguments to this fragment must include the userId of the user (in EXTRA_USER_ID) for whom
|
||||
* to display controls.
|
||||
* to display controls, or should contain the EXTRA_USER_GUEST = true.
|
||||
*/
|
||||
public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = UserDetailsSettings.class.getSimpleName();
|
||||
|
||||
private static final String KEY_SWITCH_USER = "switch_user";
|
||||
private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
|
||||
private static final String KEY_REMOVE_USER = "remove_user";
|
||||
|
||||
/** Integer extra containing the userId to manage */
|
||||
static final String EXTRA_USER_ID = "user_id";
|
||||
/** Boolean extra to indicate guest preferences */
|
||||
static final String EXTRA_USER_GUEST = "guest_user";
|
||||
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 1;
|
||||
private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2;
|
||||
private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3;
|
||||
|
||||
private UserManager mUserManager;
|
||||
@VisibleForTesting
|
||||
Preference mSwitchUserPref;
|
||||
private SwitchPreference mPhonePref;
|
||||
@VisibleForTesting
|
||||
Preference mRemoveUserPref;
|
||||
private Preference mRemoveUserPref;
|
||||
|
||||
@VisibleForTesting
|
||||
UserInfo mUserInfo;
|
||||
private UserInfo mUserInfo;
|
||||
private boolean mGuestUser;
|
||||
private Bundle mDefaultGuestRestrictions;
|
||||
|
||||
@Override
|
||||
@@ -86,28 +78,46 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
|
||||
final Context context = getActivity();
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
addPreferencesFromResource(R.xml.user_details_settings);
|
||||
mPhonePref = (SwitchPreference) findPreference(KEY_ENABLE_TELEPHONY);
|
||||
mRemoveUserPref = findPreference(KEY_REMOVE_USER);
|
||||
|
||||
initialize(context, getArguments());
|
||||
}
|
||||
mGuestUser = getArguments().getBoolean(EXTRA_USER_GUEST, false);
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mSwitchUserPref.setEnabled(canSwitchUserNow());
|
||||
if (!mGuestUser) {
|
||||
// Regular user. Get the user id from the caller.
|
||||
final int userId = getArguments().getInt(EXTRA_USER_ID, -1);
|
||||
if (userId == -1) {
|
||||
throw new RuntimeException("Arguments to this fragment must contain the user id");
|
||||
}
|
||||
mUserInfo = mUserManager.getUserInfo(userId);
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setOnPreferenceClickListener(this);
|
||||
} else {
|
||||
// These are not for an existing user, just general Guest settings.
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
// Default title is for calling and SMS. Change to calling-only here
|
||||
mPhonePref.setTitle(R.string.user_enable_calling);
|
||||
mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
|
||||
mPhonePref.setChecked(
|
||||
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
|
||||
}
|
||||
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
}
|
||||
mPhonePref.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (preference == mRemoveUserPref) {
|
||||
if (canDeleteUser()) {
|
||||
showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
}
|
||||
return true;
|
||||
} else if (preference == mSwitchUserPref) {
|
||||
if (canSwitchUserNow()) {
|
||||
switchUser();
|
||||
if (!mUserManager.isAdminUser()) {
|
||||
throw new RuntimeException("Only admins can remove a user");
|
||||
}
|
||||
showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -116,7 +126,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (Boolean.TRUE.equals(newValue)) {
|
||||
showDialog(mUserInfo.isGuest() ? DIALOG_CONFIRM_ENABLE_CALLING
|
||||
showDialog(mGuestUser ? DIALOG_CONFIRM_ENABLE_CALLING
|
||||
: DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS);
|
||||
return false;
|
||||
}
|
||||
@@ -124,135 +134,9 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return SettingsEnums.DIALOG_USER_REMOVE;
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING:
|
||||
return SettingsEnums.DIALOG_USER_ENABLE_CALLING;
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
|
||||
return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
Context context = getActivity();
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
switch (dialogId) {
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id,
|
||||
(dialog, which) -> removeUser());
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING:
|
||||
return UserDialogs.createEnablePhoneCallsDialog(getActivity(),
|
||||
(dialog, which) -> enableCallsAndSms(true));
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
|
||||
return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
|
||||
(dialog, which) -> enableCallsAndSms(true));
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
protected void showDialog(int dialogId) {
|
||||
super.showDialog(dialogId);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void initialize(Context context, Bundle arguments) {
|
||||
int userId = arguments != null ? arguments.getInt(EXTRA_USER_ID, USER_NULL) : USER_NULL;
|
||||
if (userId == USER_NULL) {
|
||||
throw new IllegalStateException("Arguments to this fragment must contain the user id");
|
||||
}
|
||||
mUserInfo = mUserManager.getUserInfo(userId);
|
||||
|
||||
mSwitchUserPref = findPreference(KEY_SWITCH_USER);
|
||||
mPhonePref = findPreference(KEY_ENABLE_TELEPHONY);
|
||||
mRemoveUserPref = findPreference(KEY_REMOVE_USER);
|
||||
|
||||
mSwitchUserPref.setTitle(
|
||||
context.getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
mUserInfo.name));
|
||||
mSwitchUserPref.setOnPreferenceClickListener(this);
|
||||
|
||||
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
} else {
|
||||
if (!Utils.isVoiceCapable(context)) { // no telephony
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
}
|
||||
|
||||
if (!mUserInfo.isGuest()) {
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setTitle(R.string.user_remove_user);
|
||||
} else {
|
||||
// These are not for an existing user, just general Guest settings.
|
||||
// Default title is for calling and SMS. Change to calling-only here
|
||||
mPhonePref.setTitle(R.string.user_enable_calling);
|
||||
mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
|
||||
mPhonePref.setChecked(
|
||||
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
|
||||
mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
|
||||
}
|
||||
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
}
|
||||
|
||||
mRemoveUserPref.setOnPreferenceClickListener(this);
|
||||
mPhonePref.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean canDeleteUser() {
|
||||
if (!mUserManager.isAdminUser()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Context context = getActivity();
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final RestrictedLockUtils.EnforcedAdmin removeDisallowedAdmin =
|
||||
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context,
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
|
||||
if (removeDisallowedAdmin != null) {
|
||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context,
|
||||
removeDisallowedAdmin);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean canSwitchUserNow() {
|
||||
return mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void switchUser() {
|
||||
try {
|
||||
ActivityManager.getService().switchUser(mUserInfo.id);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Error while switching to other user.");
|
||||
} finally {
|
||||
finishFragment();
|
||||
}
|
||||
}
|
||||
|
||||
private void enableCallsAndSms(boolean enabled) {
|
||||
void enableCallsAndSms(boolean enabled) {
|
||||
mPhonePref.setChecked(enabled);
|
||||
if (mUserInfo.isGuest()) {
|
||||
if (mGuestUser) {
|
||||
mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !enabled);
|
||||
// SMS is always disabled for guest
|
||||
mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
|
||||
@@ -262,7 +146,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
// TODO: Maybe setDefaultGuestRestrictions() can internally just set the restrictions
|
||||
// on any existing guest rather than do it here with multiple Binder calls.
|
||||
List<UserInfo> users = mUserManager.getUsers(true);
|
||||
for (UserInfo user : users) {
|
||||
for (UserInfo user: users) {
|
||||
if (user.isGuest()) {
|
||||
UserHandle userHandle = UserHandle.of(user.id);
|
||||
for (String key : mDefaultGuestRestrictions.keySet()) {
|
||||
@@ -279,7 +163,51 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void removeUser() {
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
Context context = getActivity();
|
||||
if (context == null) return null;
|
||||
switch (dialogId) {
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
removeUser();
|
||||
}
|
||||
});
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING:
|
||||
return UserDialogs.createEnablePhoneCallsDialog(getActivity(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
enableCallsAndSms(true);
|
||||
}
|
||||
});
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
|
||||
return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
enableCallsAndSms(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return SettingsEnums.DIALOG_USER_REMOVE;
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING:
|
||||
return SettingsEnums.DIALOG_USER_ENABLE_CALLING;
|
||||
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
|
||||
return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void removeUser() {
|
||||
mUserManager.removeUser(mUserInfo.id);
|
||||
finishFragment();
|
||||
}
|
||||
|
@@ -21,16 +21,18 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Preference for a user that appear on {@link UserSettings} screen.
|
||||
*/
|
||||
public class UserPreference extends RestrictedPreference {
|
||||
private static final int ALPHA_ENABLED = 255;
|
||||
private static final int ALPHA_DISABLED = 102;
|
||||
@@ -42,7 +44,8 @@ public class UserPreference extends RestrictedPreference {
|
||||
|
||||
if (p1 == null) {
|
||||
return -1;
|
||||
} else if (p2 == null) {
|
||||
}
|
||||
else if (p2 == null) {
|
||||
return 1;
|
||||
}
|
||||
int sn1 = p1.getSerialNumber();
|
||||
@@ -55,15 +58,26 @@ public class UserPreference extends RestrictedPreference {
|
||||
return 0;
|
||||
};
|
||||
|
||||
private OnClickListener mDeleteClickListener;
|
||||
private OnClickListener mSettingsClickListener;
|
||||
private int mSerialNumber = -1;
|
||||
private int mUserId = USERID_UNKNOWN;
|
||||
static final int SETTINGS_ID = R.id.manage_user;
|
||||
static final int DELETE_ID = R.id.trash_user;
|
||||
|
||||
public UserPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, USERID_UNKNOWN);
|
||||
this(context, attrs, USERID_UNKNOWN, null, null);
|
||||
}
|
||||
|
||||
UserPreference(Context context, AttributeSet attrs, int userId) {
|
||||
UserPreference(Context context, AttributeSet attrs, int userId,
|
||||
OnClickListener settingsListener,
|
||||
OnClickListener deleteListener) {
|
||||
super(context, attrs);
|
||||
if (deleteListener != null || settingsListener != null) {
|
||||
setWidgetLayoutResource(R.layout.restricted_preference_user_delete_widget);
|
||||
}
|
||||
mDeleteClickListener = deleteListener;
|
||||
mSettingsClickListener = settingsListener;
|
||||
mUserId = userId;
|
||||
useAdminDisabledSummary(true);
|
||||
}
|
||||
@@ -78,13 +92,62 @@ public class UserPreference extends RestrictedPreference {
|
||||
|
||||
@Override
|
||||
protected boolean shouldHideSecondTarget() {
|
||||
return true;
|
||||
if (isDisabledByAdmin()) {
|
||||
// Disabled by admin, show no secondary target.
|
||||
return true;
|
||||
}
|
||||
if (canDeleteUser()) {
|
||||
// Need to show delete user target so don't hide.
|
||||
return false;
|
||||
}
|
||||
// Hide if don't have advanced setting listener.
|
||||
return mSettingsClickListener == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
dimIcon(isDisabledByAdmin());
|
||||
final boolean disabledByAdmin = isDisabledByAdmin();
|
||||
dimIcon(disabledByAdmin);
|
||||
View userDeleteWidget = view.findViewById(R.id.user_delete_widget);
|
||||
if (userDeleteWidget != null) {
|
||||
userDeleteWidget.setVisibility(disabledByAdmin ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
if (!disabledByAdmin) {
|
||||
View deleteDividerView = view.findViewById(R.id.divider_delete);
|
||||
View manageDividerView = view.findViewById(R.id.divider_manage);
|
||||
View deleteView = view.findViewById(R.id.trash_user);
|
||||
if (deleteView != null) {
|
||||
if (canDeleteUser()) {
|
||||
deleteView.setVisibility(View.VISIBLE);
|
||||
deleteDividerView.setVisibility(View.VISIBLE);
|
||||
deleteView.setOnClickListener(mDeleteClickListener);
|
||||
deleteView.setTag(this);
|
||||
} else {
|
||||
deleteView.setVisibility(View.GONE);
|
||||
deleteDividerView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
ImageView manageView = (ImageView) view.findViewById(R.id.manage_user);
|
||||
if (manageView != null) {
|
||||
if (mSettingsClickListener != null) {
|
||||
manageView.setVisibility(View.VISIBLE);
|
||||
manageDividerView.setVisibility(mDeleteClickListener == null
|
||||
? View.VISIBLE : View.GONE);
|
||||
manageView.setOnClickListener(mSettingsClickListener);
|
||||
manageView.setTag(this);
|
||||
} else {
|
||||
manageView.setVisibility(View.GONE);
|
||||
manageDividerView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canDeleteUser() {
|
||||
return mDeleteClickListener != null
|
||||
&& !RestrictedLockUtilsInternal.hasBaseUserRestriction(getContext(),
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
private int getSerialNumber() {
|
||||
|
@@ -48,6 +48,7 @@ import android.util.SparseArray;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.SimpleAdapter;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -68,6 +69,7 @@ import com.android.settings.password.ChooseLockGeneric;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settings.widget.SwitchBarController;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
@@ -87,14 +89,15 @@ import java.util.Random;
|
||||
|
||||
/**
|
||||
* Screen that manages the list of users on the device.
|
||||
* Secondary users and a guest user can be created if there is no restriction.
|
||||
* Guest user is an always visible entry, even if the guest is not currently
|
||||
* active/created. It is meant for controlling properties of a guest user.
|
||||
*
|
||||
* The first user in the list is always the current user.
|
||||
* The first one is always the current user.
|
||||
* Owner is the primary user.
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class UserSettings extends SettingsPreferenceFragment
|
||||
implements Preference.OnPreferenceClickListener,
|
||||
implements Preference.OnPreferenceClickListener, View.OnClickListener,
|
||||
MultiUserSwitchBarController.OnMultiUserSwitchChangedListener,
|
||||
DialogInterface.OnDismissListener {
|
||||
|
||||
@@ -108,7 +111,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private static final String KEY_USER_LIST = "user_list";
|
||||
private static final String KEY_USER_ME = "user_me";
|
||||
private static final String KEY_USER_GUEST = "user_guest";
|
||||
private static final String KEY_ADD_GUEST = "guest_add";
|
||||
private static final String KEY_ADD_USER = "user_add";
|
||||
private static final String KEY_ADD_USER_WHEN_LOCKED = "user_settings_add_users_when_locked";
|
||||
private static final String KEY_MULTIUSER_FOOTER = "multiuser_footer";
|
||||
@@ -154,11 +156,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@VisibleForTesting
|
||||
UserPreference mMePreference;
|
||||
@VisibleForTesting
|
||||
RestrictedPreference mAddGuest;
|
||||
@VisibleForTesting
|
||||
RestrictedPreference mAddUser;
|
||||
@VisibleForTesting
|
||||
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
||||
private int mRemovingUserId = -1;
|
||||
private int mAddedUserId = 0;
|
||||
private boolean mAddingUser;
|
||||
@@ -167,6 +165,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private boolean mShouldUpdateUserList = true;
|
||||
private final Object mUserLock = new Object();
|
||||
private UserManager mUserManager;
|
||||
private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
||||
private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
|
||||
|
||||
private MultiUserSwitchBarController mSwitchBarController;
|
||||
@@ -272,17 +271,15 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
final int myUserId = UserHandle.myUserId();
|
||||
|
||||
mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST);
|
||||
mMePreference = new UserPreference(getPrefContext(), null /* attrs */, myUserId);
|
||||
mMePreference = new UserPreference(getPrefContext(), null /* attrs */, myUserId,
|
||||
null /* settings icon handler */,
|
||||
null /* delete icon handler */);
|
||||
mMePreference.setKey(KEY_USER_ME);
|
||||
mMePreference.setOnPreferenceClickListener(this);
|
||||
if (mUserCaps.mIsAdmin) {
|
||||
mMePreference.setSummary(R.string.user_admin);
|
||||
}
|
||||
|
||||
mAddGuest = findPreference(KEY_ADD_GUEST);
|
||||
mAddGuest.setOnPreferenceClickListener(this);
|
||||
|
||||
mAddUser = findPreference(KEY_ADD_USER);
|
||||
mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
|
||||
if (!mUserCaps.mCanAddRestrictedProfile) {
|
||||
// Label should only mention adding a "user", not a "profile"
|
||||
mAddUser.setTitle(R.string.user_add_user_menu);
|
||||
@@ -347,7 +344,8 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
int pos = 0;
|
||||
if (!mUserCaps.mIsAdmin && canSwitchUserNow()) {
|
||||
final boolean canSwitchUsers = mUserManager.canSwitchUsers();
|
||||
if (!mUserCaps.mIsAdmin && canSwitchUsers) {
|
||||
String nickname = mUserManager.getUserName();
|
||||
MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
|
||||
getResources().getString(R.string.user_remove_user_menu, nickname));
|
||||
@@ -388,13 +386,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
* Loads profile information for the current user.
|
||||
*/
|
||||
private void loadProfile() {
|
||||
if (isCurrentUserGuest()) {
|
||||
if (mUserCaps.mIsGuest) {
|
||||
// No need to load profile information
|
||||
mMePreference.setIcon(getEncircledDefaultIcon());
|
||||
mMePreference.setTitle(R.string.user_exit_guest_title);
|
||||
mMePreference.setSelectable(true);
|
||||
// removing a guest will result in switching back to the admin user
|
||||
mMePreference.setEnabled(canSwitchUserNow());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -417,9 +412,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
private void finishLoadProfile(String profileName) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (getActivity() == null) return;
|
||||
mMePreference.setTitle(getString(R.string.user_you, profileName));
|
||||
int myUserId = UserHandle.myUserId();
|
||||
Bitmap b = mUserManager.getUserIcon(myUserId);
|
||||
@@ -484,28 +477,38 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
private void onManageUserClicked(int userId, boolean newUser) {
|
||||
mAddingUser = false;
|
||||
UserInfo userInfo = mUserManager.getUserInfo(userId);
|
||||
if (userInfo.isRestricted() && mUserCaps.mIsAdmin) {
|
||||
if (userId == UserPreference.USERID_GUEST_DEFAULTS) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putBoolean(UserDetailsSettings.EXTRA_USER_GUEST, true);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(UserDetailsSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_guest)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
return;
|
||||
}
|
||||
UserInfo info = mUserManager.getUserInfo(userId);
|
||||
if (info.isRestricted() && mUserCaps.mIsAdmin) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_SHOW_SWITCH_USER, canSwitchUserNow());
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(RestrictedProfileSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_restrictions_title)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
} else if (userId == UserHandle.myUserId()) {
|
||||
} else if (info.id == UserHandle.myUserId()) {
|
||||
// Jump to owner info panel
|
||||
OwnerInfoSettings.show(this);
|
||||
} else {
|
||||
Bundle extras = new Bundle();
|
||||
} else if (mUserCaps.mIsAdmin) {
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(UserDetailsSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleText(userInfo.name)
|
||||
.setTitleText(info.name)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
}
|
||||
@@ -535,9 +538,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
Context context = getActivity();
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
if (context == null) return null;
|
||||
switch (dialogId) {
|
||||
case DIALOG_CONFIRM_REMOVE: {
|
||||
Dialog dlg =
|
||||
@@ -810,7 +811,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
private void removeThisUser() {
|
||||
if (!canSwitchUserNow()) {
|
||||
if (!mUserManager.canSwitchUsers()) {
|
||||
Log.w(TAG, "Cannot remove current user when switching is disabled");
|
||||
return;
|
||||
}
|
||||
@@ -881,14 +882,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
private void switchUserNow(int userId) {
|
||||
if (!canSwitchUserNow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ActivityManager.getService().switchUser(userId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Error while switching to other user.");
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,7 +894,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
*/
|
||||
private void exitGuest() {
|
||||
// Just to be safe
|
||||
if (!isCurrentUserGuest()) {
|
||||
if (!mUserCaps.mIsGuest) {
|
||||
return;
|
||||
}
|
||||
removeThisUser();
|
||||
@@ -911,12 +908,12 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
final List<UserInfo> users = mUserManager.getUsers(true);
|
||||
|
||||
final boolean voiceCapable = Utils.isVoiceCapable(context);
|
||||
final ArrayList<Integer> missingIcons = new ArrayList<>();
|
||||
final ArrayList<UserPreference> userPreferences = new ArrayList<>();
|
||||
int guestId = UserPreference.USERID_GUEST_DEFAULTS;
|
||||
userPreferences.add(mMePreference);
|
||||
|
||||
boolean canOpenUserDetails =
|
||||
mUserCaps.mIsAdmin || (canSwitchUserNow() && !mUserCaps.mDisallowSwitchUser);
|
||||
for (UserInfo user : users) {
|
||||
if (!user.supportsSwitchToByUser()) {
|
||||
// Only users that can be switched to should show up here.
|
||||
@@ -927,38 +924,37 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
if (user.id == UserHandle.myUserId()) {
|
||||
pref = mMePreference;
|
||||
} else if (user.isGuest()) {
|
||||
pref = new UserPreference(getPrefContext(), null, user.id);
|
||||
pref.setTitle(R.string.user_guest);
|
||||
pref.setIcon(getEncircledDefaultIcon());
|
||||
pref.setKey(KEY_USER_GUEST);
|
||||
userPreferences.add(pref);
|
||||
pref.setEnabled(canOpenUserDetails);
|
||||
pref.setSelectable(true);
|
||||
|
||||
if (mUserCaps.mDisallowSwitchUser) {
|
||||
pref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context));
|
||||
} else {
|
||||
pref.setDisabledByAdmin(null);
|
||||
}
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
// Skip over Guest. We add generic Guest settings after this loop
|
||||
guestId = user.id;
|
||||
continue;
|
||||
} else {
|
||||
pref = new UserPreference(getPrefContext(), null, user.id);
|
||||
// With Telephony:
|
||||
// Secondary user: Settings
|
||||
// Guest: Settings
|
||||
// Restricted Profile: There is no Restricted Profile
|
||||
// Without Telephony:
|
||||
// Secondary user: Delete
|
||||
// Guest: Nothing
|
||||
// Restricted Profile: Settings
|
||||
final boolean showSettings = mUserCaps.mIsAdmin
|
||||
&& (voiceCapable || user.isRestricted());
|
||||
final boolean showDelete = mUserCaps.mIsAdmin
|
||||
&& (!voiceCapable && !user.isRestricted() && !user.isGuest());
|
||||
pref = new UserPreference(getPrefContext(), null, user.id,
|
||||
showSettings ? this : null,
|
||||
showDelete ? this : null);
|
||||
pref.setKey("id=" + user.id);
|
||||
userPreferences.add(pref);
|
||||
if (user.isAdmin()) {
|
||||
pref.setSummary(R.string.user_admin);
|
||||
}
|
||||
pref.setTitle(user.name);
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
pref.setEnabled(canOpenUserDetails);
|
||||
pref.setSelectable(true);
|
||||
pref.setSelectable(false);
|
||||
}
|
||||
if (pref == null) {
|
||||
continue;
|
||||
}
|
||||
if (user.id != UserHandle.myUserId() && !user.isGuest() && !user.isInitialized()) {
|
||||
// sometimes after creating a guest the initialized flag isn't immediately set
|
||||
// and we don't want to show "Not set up" summary for them
|
||||
if (!isInitialized(user)) {
|
||||
if (user.isRestricted()) {
|
||||
pref.setSummary(R.string.user_summary_restricted_not_set_up);
|
||||
} else {
|
||||
@@ -966,7 +962,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
// Disallow setting up user which results in user switching when the restriction is
|
||||
// set.
|
||||
pref.setEnabled(!mUserCaps.mDisallowSwitchUser && canSwitchUserNow());
|
||||
if (!mUserCaps.mDisallowSwitchUser) {
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
pref.setSelectable(mUserManager.canSwitchUsers());
|
||||
}
|
||||
} else if (user.isRestricted()) {
|
||||
pref.setSummary(R.string.user_summary_restricted_profile);
|
||||
}
|
||||
@@ -987,13 +986,53 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
// Add a temporary entry for the user being created
|
||||
if (mAddingUser) {
|
||||
UserPreference pref = new UserPreference(getPrefContext(), null,
|
||||
UserPreference.USERID_UNKNOWN);
|
||||
UserPreference.USERID_UNKNOWN, null, null);
|
||||
pref.setEnabled(false);
|
||||
pref.setTitle(mAddingUserName);
|
||||
pref.setIcon(getEncircledDefaultIcon());
|
||||
userPreferences.add(pref);
|
||||
}
|
||||
|
||||
// Check if Guest tile should be added.
|
||||
if (!mUserCaps.mIsGuest && (mUserCaps.mCanAddGuest ||
|
||||
mUserCaps.mDisallowAddUserSetByAdmin)) {
|
||||
// Add a virtual Guest user for guest defaults
|
||||
UserPreference pref = new UserPreference(getPrefContext(), null,
|
||||
UserPreference.USERID_GUEST_DEFAULTS,
|
||||
mUserCaps.mIsAdmin && voiceCapable ? this : null /* settings icon handler */,
|
||||
null /* delete icon handler */);
|
||||
pref.setTitle(R.string.user_guest);
|
||||
pref.setIcon(getEncircledDefaultIcon());
|
||||
pref.setKey(KEY_USER_GUEST);
|
||||
userPreferences.add(pref);
|
||||
if (mUserCaps.mDisallowAddUser) {
|
||||
pref.setDisabledByAdmin(mUserCaps.mEnforcedAdmin);
|
||||
} else if (mUserCaps.mDisallowSwitchUser) {
|
||||
pref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context));
|
||||
} else {
|
||||
pref.setDisabledByAdmin(null);
|
||||
}
|
||||
if (!mUserManager.canSwitchUsers()) {
|
||||
pref.setSelectable(false);
|
||||
}
|
||||
int finalGuestId = guestId;
|
||||
pref.setOnPreferenceClickListener(preference -> {
|
||||
int id = finalGuestId;
|
||||
if (id == UserPreference.USERID_GUEST_DEFAULTS) {
|
||||
UserInfo guest = mUserManager.createGuest(
|
||||
getContext(), preference.getTitle().toString());
|
||||
if (guest != null) {
|
||||
id = guest.id;
|
||||
}
|
||||
}
|
||||
try {
|
||||
ActivityManager.getService().switchUser(id);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Sort list of users by serialNum
|
||||
Collections.sort(userPreferences, UserPreference.SERIAL_NUMBER_COMPARATOR);
|
||||
@@ -1025,7 +1064,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
mMultiUserFooterPreferenceController.updateState(multiUserFooterPrefence);
|
||||
mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
|
||||
|
||||
updateAddGuest(context, users.stream().anyMatch(UserInfo::isGuest));
|
||||
updateAddUser(context);
|
||||
|
||||
if (!mUserCaps.mUserSwitcherEnabled) {
|
||||
@@ -1039,38 +1077,15 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
}
|
||||
|
||||
private boolean isCurrentUserGuest() {
|
||||
return mUserCaps.mIsGuest;
|
||||
}
|
||||
|
||||
private boolean canSwitchUserNow() {
|
||||
return mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK;
|
||||
}
|
||||
|
||||
private void updateAddGuest(Context context, boolean isGuestAlreadyCreated) {
|
||||
if (!isGuestAlreadyCreated && mUserCaps.mCanAddGuest
|
||||
&& WizardManagerHelper.isDeviceProvisioned(context)
|
||||
&& mUserCaps.mUserSwitcherEnabled) {
|
||||
mAddGuest.setVisible(true);
|
||||
mAddGuest.setIcon(getEncircledDefaultIcon());
|
||||
mAddGuest.setEnabled(canSwitchUserNow());
|
||||
mAddGuest.setSelectable(true);
|
||||
} else {
|
||||
mAddGuest.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAddUser(Context context) {
|
||||
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin)
|
||||
&& WizardManagerHelper.isDeviceProvisioned(context)
|
||||
&& mUserCaps.mUserSwitcherEnabled) {
|
||||
mAddUser.setVisible(true);
|
||||
mAddUser.setSelectable(true);
|
||||
final boolean canAddMoreUsers = mUserManager.canAddMoreUsers();
|
||||
mAddUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
|
||||
if (!canAddMoreUsers) {
|
||||
mAddUser.setSummary(
|
||||
getString(R.string.user_add_max_count, getRealUsersCount()));
|
||||
final boolean moreUsers = mUserManager.canAddMoreUsers();
|
||||
mAddUser.setEnabled(moreUsers && !mAddingUser && mUserManager.canSwitchUsers());
|
||||
if (!moreUsers) {
|
||||
mAddUser.setSummary(getString(R.string.user_add_max_count, getMaxRealUsers()));
|
||||
} else {
|
||||
mAddUser.setSummary(null);
|
||||
}
|
||||
@@ -1083,15 +1098,18 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of non-guest non-managed users
|
||||
*/
|
||||
@VisibleForTesting
|
||||
int getRealUsersCount() {
|
||||
return (int) mUserManager.getUsers()
|
||||
.stream()
|
||||
.filter(user -> !user.isGuest() && !user.isProfile())
|
||||
.count();
|
||||
private int getMaxRealUsers() {
|
||||
// guest is not counted against getMaxSupportedUsers() number
|
||||
final int maxUsersAndGuest = UserManager.getMaxSupportedUsers() + 1;
|
||||
final List<UserInfo> users = mUserManager.getUsers();
|
||||
// managed profiles are counted against getMaxSupportedUsers()
|
||||
int managedProfiles = 0;
|
||||
for (UserInfo user : users) {
|
||||
if (user.isManagedProfile()) {
|
||||
managedProfiles++;
|
||||
}
|
||||
}
|
||||
return maxUsersAndGuest - managedProfiles;
|
||||
}
|
||||
|
||||
private void loadIconsAsync(List<Integer> missingIcons) {
|
||||
@@ -1133,12 +1151,12 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference pref) {
|
||||
if (pref == mMePreference) {
|
||||
if (isCurrentUserGuest()) {
|
||||
if (mUserCaps.mIsGuest) {
|
||||
showDialog(DIALOG_CONFIRM_EXIT_GUEST);
|
||||
return true;
|
||||
}
|
||||
// If this is a limited user, launch the user info settings instead of profile editor
|
||||
if (mUserManager.isRestrictedProfile()) {
|
||||
if (mUserManager.isLinkedUser()) {
|
||||
onManageUserClicked(UserHandle.myUserId(), false);
|
||||
} else {
|
||||
showDialog(DIALOG_USER_PROFILE_EDITOR);
|
||||
@@ -1147,11 +1165,9 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
int userId = ((UserPreference) pref).getUserId();
|
||||
// Get the latest status of the user
|
||||
UserInfo user = mUserManager.getUserInfo(userId);
|
||||
if (!user.isInitialized()) {
|
||||
if (!isInitialized(user)) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(
|
||||
MESSAGE_SETUP_USER, user.id, user.serialNumber));
|
||||
} else {
|
||||
onManageUserClicked(userId, false);
|
||||
}
|
||||
} else if (pref == mAddUser) {
|
||||
// If we allow both types, show a picker, otherwise directly go to
|
||||
@@ -1161,19 +1177,39 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
} else {
|
||||
onAddUserClicked(USER_TYPE_USER);
|
||||
}
|
||||
} else if (pref == mAddGuest) {
|
||||
UserInfo guest = mUserManager.createGuest(
|
||||
getContext(), getString(com.android.settingslib.R.string.user_guest));
|
||||
switchUserNow(guest.id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInitialized(UserInfo user) {
|
||||
return (user.flags & UserInfo.FLAG_INITIALIZED) != 0;
|
||||
}
|
||||
|
||||
private Drawable encircle(Bitmap icon) {
|
||||
Drawable circled = CircleFramedDrawable.getInstance(getActivity(), icon);
|
||||
return circled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getTag() instanceof UserPreference) {
|
||||
int userId = ((UserPreference) v.getTag()).getUserId();
|
||||
if (v.getId() == UserPreference.DELETE_ID) {
|
||||
final EnforcedAdmin removeDisallowedAdmin =
|
||||
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getContext(),
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
|
||||
if (removeDisallowedAdmin != null) {
|
||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
|
||||
removeDisallowedAdmin);
|
||||
} else {
|
||||
onRemoveUserClicked(userId);
|
||||
}
|
||||
} else if (v.getId() == UserPreference.SETTINGS_ID) {
|
||||
onManageUserClicked(userId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
synchronized (mUserLock) {
|
||||
|
Reference in New Issue
Block a user