Added SearchIndexProvider for UserSettings

It enables customizations for certain cases like whether the user is able to
create restricted profiles or multiuser UI is disabled.

Bug: 21197002
Change-Id: Ia672c0f9bb451877f8debe04438b46cb2b7e9242
This commit is contained in:
Fyodor Kupolov
2015-05-15 17:16:15 -07:00
parent 3a310719d8
commit c9a95ef6e7
2 changed files with 103 additions and 46 deletions

View File

@@ -208,7 +208,7 @@ public final class SearchIndexableResources {
sResMap.put(UserSettings.class.getName(), sResMap.put(UserSettings.class.getName(),
new SearchIndexableResource( new SearchIndexableResource(
Ranking.getRankForClassName(UserSettings.class.getName()), Ranking.getRankForClassName(UserSettings.class.getName()),
R.xml.user_settings, NO_DATA_RES_ID,
UserSettings.class.getName(), UserSettings.class.getName(),
R.drawable.ic_settings_multiuser)); R.drawable.ic_settings_multiuser));

View File

@@ -22,7 +22,6 @@ import android.app.Activity;
import android.app.ActivityManagerNative; import android.app.ActivityManagerNative;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@@ -66,6 +65,9 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.drawable.CircleFramedDrawable; import com.android.settings.drawable.CircleFramedDrawable;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -83,7 +85,7 @@ import java.util.List;
public class UserSettings extends SettingsPreferenceFragment public class UserSettings extends SettingsPreferenceFragment
implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener, implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
Preference.OnPreferenceChangeListener, Preference.OnPreferenceChangeListener,
EditUserInfoController.OnContentChangedCallback { EditUserInfoController.OnContentChangedCallback, Indexable {
private static final String TAG = "UserSettings"; private static final String TAG = "UserSettings";
@@ -131,15 +133,11 @@ public class UserSettings extends SettingsPreferenceFragment
private int mRemovingUserId = -1; private int mRemovingUserId = -1;
private int mAddedUserId = 0; private int mAddedUserId = 0;
private boolean mAddingUser; private boolean mAddingUser;
private boolean mEnabled = true; private UserCapabilities mUserCaps;
private boolean mCanAddUser = true;
private boolean mCanAddRestrictedProfile = true;
private final Object mUserLock = new Object(); private final Object mUserLock = new Object();
private UserManager mUserManager; private UserManager mUserManager;
private SparseArray<Bitmap> mUserIcons = new SparseArray<Bitmap>(); private SparseArray<Bitmap> mUserIcons = new SparseArray<Bitmap>();
private boolean mIsOwner = UserHandle.myUserId() == UserHandle.USER_OWNER;
private boolean mIsGuest;
private EditUserInfoController mEditUserInfoController = private EditUserInfoController mEditUserInfoController =
new EditUserInfoController(); new EditUserInfoController();
@@ -198,16 +196,13 @@ public class UserSettings extends SettingsPreferenceFragment
mEditUserInfoController.onRestoreInstanceState(icicle); mEditUserInfoController.onRestoreInstanceState(icicle);
} }
final Context context = getActivity(); final Context context = getActivity();
mUserCaps = UserCapabilities.create(context);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
boolean hasMultipleUsers = mUserManager.getUserCount() > 1; if (!mUserCaps.mEnabled) {
if ((!UserManager.supportsMultipleUsers())
|| Utils.isMonkeyRunning()) {
mEnabled = false;
return; return;
} }
final int myUserId = UserHandle.myUserId(); final int myUserId = UserHandle.myUserId();
mIsGuest = mUserManager.getUserInfo(myUserId).isGuest();
addPreferencesFromResource(R.xml.user_settings); addPreferencesFromResource(R.xml.user_settings);
mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST); mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST);
@@ -216,25 +211,15 @@ public class UserSettings extends SettingsPreferenceFragment
null /* delete icon handler */); null /* delete icon handler */);
mMePreference.setKey(KEY_USER_ME); mMePreference.setKey(KEY_USER_ME);
mMePreference.setOnPreferenceClickListener(this); mMePreference.setOnPreferenceClickListener(this);
if (mIsOwner) { if (mUserCaps.mIsOwner) {
mMePreference.setSummary(R.string.user_owner); mMePreference.setSummary(R.string.user_owner);
} }
mAddUser = findPreference(KEY_ADD_USER); mAddUser = findPreference(KEY_ADD_USER);
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
Context.DEVICE_POLICY_SERVICE);
// No restricted profiles for tablets with a device owner, or phones.
if (dpm.getDeviceOwner() != null || Utils.isVoiceCapable(context)) {
mCanAddRestrictedProfile = false;
}
// Determine if add user/profile button should be visible // Determine if add user/profile button should be visible
if (!mIsOwner || UserManager.getMaxSupportedUsers() < 2 if (mUserCaps.mCanAddUser) {
|| !UserManager.supportsMultipleUsers()
|| mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
mCanAddUser = false;
} else {
mAddUser.setOnPreferenceClickListener(this); mAddUser.setOnPreferenceClickListener(this);
// change label to only mention user, if restricted profiles are not supported // change label to only mention user, if restricted profiles are not supported
if (!mCanAddRestrictedProfile) { if (!mUserCaps.mCanAddRestrictedProfile) {
mAddUser.setTitle(R.string.user_add_user_menu); mAddUser.setTitle(R.string.user_add_user_menu);
} }
} }
@@ -250,7 +235,7 @@ public class UserSettings extends SettingsPreferenceFragment
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (!mEnabled) return; if (!mUserCaps.mEnabled) return;
loadProfile(); loadProfile();
updateUserList(); updateUserList();
@@ -260,7 +245,7 @@ public class UserSettings extends SettingsPreferenceFragment
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if (!mEnabled) return; if (!mUserCaps.mEnabled) return;
getActivity().unregisterReceiver(mUserChangeReceiver); getActivity().unregisterReceiver(mUserChangeReceiver);
} }
@@ -283,13 +268,13 @@ public class UserSettings extends SettingsPreferenceFragment
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
int pos = 0; int pos = 0;
UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
if (!mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) { if (!mUserCaps.mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) {
String nickname = mUserManager.getUserName(); String nickname = mUserManager.getUserName();
MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++, MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
getResources().getString(R.string.user_remove_user_menu, nickname)); getResources().getString(R.string.user_remove_user_menu, nickname));
removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
} }
if (mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) { if (mUserCaps.mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
MenuItem allowAddOnLockscreen = menu.add(0, MENU_ADD_ON_LOCKSCREEN, pos++, MenuItem allowAddOnLockscreen = menu.add(0, MENU_ADD_ON_LOCKSCREEN, pos++,
R.string.user_add_on_lockscreen_menu); R.string.user_add_on_lockscreen_menu);
allowAddOnLockscreen.setCheckable(true); allowAddOnLockscreen.setCheckable(true);
@@ -320,7 +305,7 @@ public class UserSettings extends SettingsPreferenceFragment
* Loads profile information for the current user. * Loads profile information for the current user.
*/ */
private void loadProfile() { private void loadProfile() {
if (mIsGuest) { if (mUserCaps.mIsGuest) {
// No need to load profile information // No need to load profile information
mMePreference.setIcon(getEncircledDefaultIcon()); mMePreference.setIcon(getEncircledDefaultIcon());
mMePreference.setTitle(R.string.user_exit_guest_title); mMePreference.setTitle(R.string.user_exit_guest_title);
@@ -451,7 +436,7 @@ public class UserSettings extends SettingsPreferenceFragment
return; return;
} }
UserInfo info = mUserManager.getUserInfo(userId); UserInfo info = mUserManager.getUserInfo(userId);
if (info.isRestricted() && mIsOwner) { if (info.isRestricted() && mUserCaps.mIsOwner) {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId); extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser); extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
@@ -462,7 +447,7 @@ public class UserSettings extends SettingsPreferenceFragment
} else if (info.id == UserHandle.myUserId()) { } else if (info.id == UserHandle.myUserId()) {
// Jump to owner info panel // Jump to owner info panel
OwnerInfoSettings.show(this); OwnerInfoSettings.show(this);
} else if (mIsOwner) { } else if (mUserCaps.mIsOwner) {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId); extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
((SettingsActivity) getActivity()).startPreferencePanel( ((SettingsActivity) getActivity()).startPreferencePanel(
@@ -624,7 +609,7 @@ public class UserSettings extends SettingsPreferenceFragment
} }
case DIALOG_USER_PROFILE_EDITOR: { case DIALOG_USER_PROFILE_EDITOR: {
Dialog dlg = mEditUserInfoController.createDialog( Dialog dlg = mEditUserInfoController.createDialog(
(Fragment) this, this,
mMePreference.getIcon(), mMePreference.getIcon(),
mMePreference.getTitle(), mMePreference.getTitle(),
R.string.profile_info_settings_title, R.string.profile_info_settings_title,
@@ -668,7 +653,7 @@ public class UserSettings extends SettingsPreferenceFragment
//updateUserList(); //updateUserList();
new Thread() { new Thread() {
public void run() { public void run() {
UserInfo user = null; UserInfo user;
// Could take a few seconds // Could take a few seconds
if (userType == USER_TYPE_USER) { if (userType == USER_TYPE_USER) {
user = createTrustedUser(); user = createTrustedUser();
@@ -704,7 +689,7 @@ public class UserSettings extends SettingsPreferenceFragment
*/ */
private void exitGuest() { private void exitGuest() {
// Just to be safe // Just to be safe
if (!mIsGuest) { if (!mUserCaps.mIsGuest) {
return; return;
} }
removeThisUser(); removeThisUser();
@@ -740,8 +725,9 @@ public class UserSettings extends SettingsPreferenceFragment
// Secondary user: Delete // Secondary user: Delete
// Guest: Nothing // Guest: Nothing
// Restricted Profile: Settings // Restricted Profile: Settings
final boolean showSettings = mIsOwner && (voiceCapable || user.isRestricted()); final boolean showSettings = mUserCaps.mIsOwner
final boolean showDelete = mIsOwner && (voiceCapable || user.isRestricted());
final boolean showDelete = mUserCaps.mIsOwner
&& (!voiceCapable && !user.isRestricted() && !user.isGuest()); && (!voiceCapable && !user.isRestricted() && !user.isGuest());
pref = new UserPreference(context, null, user.id, pref = new UserPreference(context, null, user.id,
showSettings ? this : null, showSettings ? this : null,
@@ -791,7 +777,7 @@ public class UserSettings extends SettingsPreferenceFragment
// Add a virtual Guest user for guest defaults // Add a virtual Guest user for guest defaults
UserPreference pref = new UserPreference(getActivity(), null, UserPreference pref = new UserPreference(getActivity(), null,
UserPreference.USERID_GUEST_DEFAULTS, UserPreference.USERID_GUEST_DEFAULTS,
mIsOwner && voiceCapable? this : null /* settings icon handler */, mUserCaps.mIsOwner && voiceCapable? this : null /* settings icon handler */,
null /* delete icon handler */); null /* delete icon handler */);
pref.setTitle(R.string.user_guest); pref.setTitle(R.string.user_guest);
pref.setIcon(getEncircledDefaultIcon()); pref.setIcon(getEncircledDefaultIcon());
@@ -816,7 +802,7 @@ public class UserSettings extends SettingsPreferenceFragment
// "User & Profiles", otherwise the category is skipped and elements are added directly // "User & Profiles", otherwise the category is skipped and elements are added directly
// to preferenceScreen // to preferenceScreen
PreferenceGroup groupToAddUsers; PreferenceGroup groupToAddUsers;
if (mCanAddRestrictedProfile) { if (mUserCaps.mCanAddRestrictedProfile) {
mUserListCategory.removeAll(); mUserListCategory.removeAll();
mUserListCategory.setOrder(Preference.DEFAULT_ORDER); mUserListCategory.setOrder(Preference.DEFAULT_ORDER);
preferenceScreen.addPreference(mUserListCategory); preferenceScreen.addPreference(mUserListCategory);
@@ -830,7 +816,7 @@ public class UserSettings extends SettingsPreferenceFragment
} }
// Append Add user to the end of the list // Append Add user to the end of the list
if (mCanAddUser) { if (mUserCaps.mCanAddUser) {
boolean moreUsers = mUserManager.canAddMoreUsers(); boolean moreUsers = mUserManager.canAddMoreUsers();
mAddUser.setEnabled(moreUsers); mAddUser.setEnabled(moreUsers);
mAddUser.setOrder(Preference.DEFAULT_ORDER); mAddUser.setOrder(Preference.DEFAULT_ORDER);
@@ -839,7 +825,7 @@ public class UserSettings extends SettingsPreferenceFragment
} }
private boolean shouldShowGuestUserPreference(List<UserInfo> users) { private boolean shouldShowGuestUserPreference(List<UserInfo> users) {
boolean showGuestPreference = !mIsGuest; boolean showGuestPreference = !mUserCaps.mIsGuest;
// If user has DISALLOW_ADD_USER don't allow creating a guest either. // If user has DISALLOW_ADD_USER don't allow creating a guest either.
if (showGuestPreference && mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) { if (showGuestPreference && mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
showGuestPreference = false; showGuestPreference = false;
@@ -856,7 +842,6 @@ public class UserSettings extends SettingsPreferenceFragment
private void loadIconsAsync(List<Integer> missingIcons) { private void loadIconsAsync(List<Integer> missingIcons) {
final Resources resources = getResources();
new AsyncTask<List<Integer>, Void, Void>() { new AsyncTask<List<Integer>, Void, Void>() {
@Override @Override
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
@@ -911,7 +896,7 @@ public class UserSettings extends SettingsPreferenceFragment
@Override @Override
public boolean onPreferenceClick(Preference pref) { public boolean onPreferenceClick(Preference pref) {
if (pref == mMePreference) { if (pref == mMePreference) {
if (mIsGuest) { if (mUserCaps.mIsGuest) {
showDialog(DIALOG_CONFIRM_EXIT_GUEST); showDialog(DIALOG_CONFIRM_EXIT_GUEST);
return true; return true;
} }
@@ -938,7 +923,7 @@ public class UserSettings extends SettingsPreferenceFragment
} else if (pref == mAddUser) { } else if (pref == mAddUser) {
// If we allow both types, show a picker, otherwise directly go to // If we allow both types, show a picker, otherwise directly go to
// flow for full user. // flow for full user.
if (mCanAddRestrictedProfile) { if (mUserCaps.mCanAddRestrictedProfile) {
showDialog(DIALOG_CHOOSE_USER_TYPE); showDialog(DIALOG_CHOOSE_USER_TYPE);
} else { } else {
onAddUserClicked(USER_TYPE_USER); onAddUserClicked(USER_TYPE_USER);
@@ -958,7 +943,7 @@ public class UserSettings extends SettingsPreferenceFragment
// No guest user. Create one, if there's no restriction. // No guest user. Create one, if there's no restriction.
// If it is not the primary user, then adding users from lockscreen must be enabled // If it is not the primary user, then adding users from lockscreen must be enabled
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER) if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)
|| (!mIsOwner && Settings.Global.getInt(getContentResolver(), || (!mUserCaps.mIsOwner && Settings.Global.getInt(getContentResolver(),
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 1)) { Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 1)) {
Log.i(TAG, "Blocking guest creation because it is restricted"); Log.i(TAG, "Blocking guest creation because it is restricted");
return; return;
@@ -1030,4 +1015,76 @@ public class UserSettings extends SettingsPreferenceFragment
public void onLabelChanged(CharSequence label) { public void onLabelChanged(CharSequence label) {
mMePreference.setTitle(label); mMePreference.setTitle(label);
} }
private static class UserCapabilities {
boolean mEnabled = true;
boolean mCanAddUser = true;
boolean mCanAddRestrictedProfile = true;
boolean mIsOwner = UserHandle.myUserId() == UserHandle.USER_OWNER;
boolean mIsGuest;
public static UserCapabilities create(Context context) {
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
UserCapabilities caps = new UserCapabilities();
if (!UserManager.supportsMultipleUsers() || Utils.isMonkeyRunning()) {
caps.mEnabled = false;
return caps;
}
if (!caps.mIsOwner || UserManager.getMaxSupportedUsers() < 2
|| !UserManager.supportsMultipleUsers()
|| userManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
caps.mCanAddUser = false;
}
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
Context.DEVICE_POLICY_SERVICE);
// No restricted profiles for tablets with a device owner, or phones.
if (dpm.getDeviceOwner() != null || Utils.isVoiceCapable(context)) {
caps.mCanAddRestrictedProfile = false;
}
final int myUserId = UserHandle.myUserId();
caps.mIsGuest = userManager.getUserInfo(myUserId).isGuest();
return caps;
}
@Override
public String toString() {
return "UserCapabilities{" +
"mEnabled=" + mEnabled +
", mCanAddUser=" + mCanAddUser +
", mCanAddRestrictedProfile=" + mCanAddRestrictedProfile +
", mIsOwner=" + mIsOwner +
", mIsGuest=" + mIsGuest +
'}';
}
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<>();
final UserCapabilities userCaps = UserCapabilities.create(context);
if (!userCaps.mEnabled) {
return result;
}
final Resources res = context.getResources();
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.user_settings_title);
data.screenTitle = res.getString(R.string.user_settings_title);
result.add(data);
if (userCaps.mCanAddUser) {
data = new SearchIndexableRaw(context);
data.title = res.getString(userCaps.mCanAddRestrictedProfile ?
R.string.user_add_user_or_profile_menu
: R.string.user_add_user_menu);
data.screenTitle = res.getString(R.string.user_settings_title);
result.add(data);
}
return result;
}
};
} }