If the user photo was deleted in the Myself contact, the change was not reflected neither in Settings/Users nor in expanded status bar. This was because the ProfileUpdateReceiver did not handle the case where the updated image was null (deleted). Fixed by assigning default user icon in UserManager if no photo found in the profile update. AOSP change: https://android-review.googlesource.com/#/c/153137 Bug: 28031914 Change-Id: I2f452f78dcf777414f50b133b1a9cee334bbd9a8
1149 lines
46 KiB
Java
1149 lines
46 KiB
Java
/*
|
|
* Copyright (C) 2012 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.settings.users;
|
|
|
|
import android.app.Activity;
|
|
import android.app.ActivityManagerNative;
|
|
import android.app.AlertDialog;
|
|
import android.app.Dialog;
|
|
import android.app.admin.DevicePolicyManager;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.content.SharedPreferences;
|
|
import android.content.pm.ResolveInfo;
|
|
import android.content.pm.UserInfo;
|
|
import android.content.res.Resources;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.os.AsyncTask;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
import android.os.RemoteException;
|
|
import android.os.UserHandle;
|
|
import android.os.UserManager;
|
|
import android.provider.Settings;
|
|
import android.support.v7.preference.Preference;
|
|
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
|
import android.support.v7.preference.PreferenceGroup;
|
|
import android.support.v7.preference.PreferenceScreen;
|
|
import android.util.Log;
|
|
import android.util.SparseArray;
|
|
import android.view.Menu;
|
|
import android.view.MenuInflater;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.view.View.OnClickListener;
|
|
import android.widget.SimpleAdapter;
|
|
|
|
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
|
import com.android.internal.widget.LockPatternUtils;
|
|
import com.android.settings.ChooseLockGeneric;
|
|
import com.android.settings.DimmableIconPreference;
|
|
import com.android.settings.OwnerInfoSettings;
|
|
import com.android.settings.R;
|
|
import com.android.settings.SettingsActivity;
|
|
import com.android.settings.SettingsPreferenceFragment;
|
|
import com.android.settings.Utils;
|
|
import com.android.settings.dashboard.SummaryLoader;
|
|
import com.android.settings.search.BaseSearchIndexProvider;
|
|
import com.android.settings.search.Indexable;
|
|
import com.android.settings.search.SearchIndexableRaw;
|
|
import com.android.settingslib.RestrictedLockUtils;
|
|
import com.android.settingslib.RestrictedSwitchPreference;
|
|
import com.android.settingslib.drawable.CircleFramedDrawable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
|
|
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
|
|
|
/**
|
|
* Screen that manages the list of users on the device.
|
|
* 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 one is always the current user.
|
|
* Owner is the primary user.
|
|
*/
|
|
public class UserSettings extends SettingsPreferenceFragment
|
|
implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
|
|
Preference.OnPreferenceChangeListener,
|
|
EditUserInfoController.OnContentChangedCallback, Indexable {
|
|
|
|
private static final String TAG = "UserSettings";
|
|
|
|
/** UserId of the user being removed */
|
|
private static final String SAVE_REMOVING_USER = "removing_user";
|
|
/** UserId of the user that was just added */
|
|
private static final String SAVE_ADDING_USER = "adding_user";
|
|
|
|
private static final String KEY_USER_LIST = "user_list";
|
|
private static final String KEY_USER_ME = "user_me";
|
|
private static final String KEY_ADD_USER = "user_add";
|
|
private static final String KEY_EMERGENCY_INFO = "emergency_info";
|
|
|
|
private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENGY_INFO";
|
|
|
|
private static final int MENU_REMOVE_USER = Menu.FIRST;
|
|
|
|
private static final int DIALOG_CONFIRM_REMOVE = 1;
|
|
private static final int DIALOG_ADD_USER = 2;
|
|
private static final int DIALOG_SETUP_USER = 3;
|
|
private static final int DIALOG_SETUP_PROFILE = 4;
|
|
private static final int DIALOG_USER_CANNOT_MANAGE = 5;
|
|
private static final int DIALOG_CHOOSE_USER_TYPE = 6;
|
|
private static final int DIALOG_NEED_LOCKSCREEN = 7;
|
|
private static final int DIALOG_CONFIRM_EXIT_GUEST = 8;
|
|
private static final int DIALOG_USER_PROFILE_EDITOR = 9;
|
|
|
|
private static final int MESSAGE_UPDATE_LIST = 1;
|
|
private static final int MESSAGE_SETUP_USER = 2;
|
|
private static final int MESSAGE_CONFIG_USER = 3;
|
|
|
|
private static final int USER_TYPE_USER = 1;
|
|
private static final int USER_TYPE_RESTRICTED_PROFILE = 2;
|
|
|
|
private static final int REQUEST_CHOOSE_LOCK = 10;
|
|
|
|
private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED =
|
|
"key_add_user_long_message_displayed";
|
|
|
|
private static final String KEY_TITLE = "title";
|
|
private static final String KEY_SUMMARY = "summary";
|
|
|
|
private PreferenceGroup mUserListCategory;
|
|
private UserPreference mMePreference;
|
|
private DimmableIconPreference mAddUser;
|
|
private PreferenceGroup mLockScreenSettings;
|
|
private RestrictedSwitchPreference mAddUserWhenLocked;
|
|
private Preference mEmergencyInfoPreference;
|
|
private int mRemovingUserId = -1;
|
|
private int mAddedUserId = 0;
|
|
private boolean mAddingUser;
|
|
private String mAddingUserName;
|
|
private UserCapabilities mUserCaps;
|
|
private boolean mShouldUpdateUserList = true;
|
|
private final Object mUserLock = new Object();
|
|
private UserManager mUserManager;
|
|
private SparseArray<Bitmap> mUserIcons = new SparseArray<Bitmap>();
|
|
|
|
private EditUserInfoController mEditUserInfoController =
|
|
new EditUserInfoController();
|
|
|
|
// A place to cache the generated default avatar
|
|
private Drawable mDefaultIconDrawable;
|
|
|
|
private Handler mHandler = new Handler() {
|
|
@Override
|
|
public void handleMessage(Message msg) {
|
|
switch (msg.what) {
|
|
case MESSAGE_UPDATE_LIST:
|
|
updateUserList();
|
|
break;
|
|
case MESSAGE_SETUP_USER:
|
|
onUserCreated(msg.arg1);
|
|
break;
|
|
case MESSAGE_CONFIG_USER:
|
|
onManageUserClicked(msg.arg1, true);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
if (intent.getAction().equals(Intent.ACTION_USER_REMOVED)) {
|
|
mRemovingUserId = -1;
|
|
} else if (intent.getAction().equals(Intent.ACTION_USER_INFO_CHANGED)) {
|
|
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
|
|
if (userHandle != -1) {
|
|
mUserIcons.remove(userHandle);
|
|
}
|
|
}
|
|
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
|
|
}
|
|
};
|
|
|
|
@Override
|
|
protected int getMetricsCategory() {
|
|
return MetricsEvent.USER;
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(Bundle icicle) {
|
|
super.onCreate(icicle);
|
|
|
|
if (icicle != null) {
|
|
if (icicle.containsKey(SAVE_ADDING_USER)) {
|
|
mAddedUserId = icicle.getInt(SAVE_ADDING_USER);
|
|
}
|
|
if (icicle.containsKey(SAVE_REMOVING_USER)) {
|
|
mRemovingUserId = icicle.getInt(SAVE_REMOVING_USER);
|
|
}
|
|
mEditUserInfoController.onRestoreInstanceState(icicle);
|
|
}
|
|
final Context context = getActivity();
|
|
mUserCaps = UserCapabilities.create(context);
|
|
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
|
if (!mUserCaps.mEnabled) {
|
|
return;
|
|
}
|
|
|
|
final int myUserId = UserHandle.myUserId();
|
|
|
|
addPreferencesFromResource(R.xml.user_settings);
|
|
mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST);
|
|
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);
|
|
}
|
|
mAddUser = (DimmableIconPreference) findPreference(KEY_ADD_USER);
|
|
// Determine if add user/profile button should be visible
|
|
if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(getActivity())) {
|
|
mAddUser.setOnPreferenceClickListener(this);
|
|
// change label to only mention user, if restricted profiles are not supported
|
|
if (!mUserCaps.mCanAddRestrictedProfile) {
|
|
mAddUser.setTitle(R.string.user_add_user_menu);
|
|
}
|
|
}
|
|
mLockScreenSettings = (PreferenceGroup) findPreference("lock_screen_settings");
|
|
mAddUserWhenLocked = (RestrictedSwitchPreference) findPreference("add_users_when_locked");
|
|
mEmergencyInfoPreference = findPreference(KEY_EMERGENCY_INFO);
|
|
setHasOptionsMenu(true);
|
|
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
|
|
filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
|
|
context.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, mHandler);
|
|
loadProfile();
|
|
updateUserList();
|
|
mShouldUpdateUserList = false;
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
|
|
if (!mUserCaps.mEnabled) return;
|
|
if (mShouldUpdateUserList) {
|
|
mUserCaps.updateAddUserCapabilities(getActivity());
|
|
loadProfile();
|
|
updateUserList();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
mShouldUpdateUserList = true;
|
|
super.onPause();
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
super.onDestroy();
|
|
|
|
if (!mUserCaps.mEnabled) return;
|
|
|
|
getActivity().unregisterReceiver(mUserChangeReceiver);
|
|
}
|
|
|
|
@Override
|
|
public void onSaveInstanceState(Bundle outState) {
|
|
super.onSaveInstanceState(outState);
|
|
mEditUserInfoController.onSaveInstanceState(outState);
|
|
outState.putInt(SAVE_ADDING_USER, mAddedUserId);
|
|
outState.putInt(SAVE_REMOVING_USER, mRemovingUserId);
|
|
}
|
|
|
|
@Override
|
|
public void startActivityForResult(Intent intent, int requestCode) {
|
|
mEditUserInfoController.startingActivityForResult();
|
|
super.startActivityForResult(intent, requestCode);
|
|
}
|
|
|
|
@Override
|
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
int pos = 0;
|
|
UserManager um = getContext().getSystemService(UserManager.class);
|
|
boolean allowRemoveUser = !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
|
|
boolean canSwitchUsers = um.canSwitchUsers();
|
|
if (!mUserCaps.mIsAdmin && allowRemoveUser && canSwitchUsers) {
|
|
String nickname = mUserManager.getUserName();
|
|
MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
|
|
getResources().getString(R.string.user_remove_user_menu, nickname));
|
|
removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
|
}
|
|
super.onCreateOptionsMenu(menu, inflater);
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
final int itemId = item.getItemId();
|
|
if (itemId == MENU_REMOVE_USER) {
|
|
onRemoveUserClicked(UserHandle.myUserId());
|
|
return true;
|
|
} else {
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads profile information for the current user.
|
|
*/
|
|
private void loadProfile() {
|
|
if (mUserCaps.mIsGuest) {
|
|
// No need to load profile information
|
|
mMePreference.setIcon(getEncircledDefaultIcon());
|
|
mMePreference.setTitle(R.string.user_exit_guest_title);
|
|
return;
|
|
}
|
|
|
|
new AsyncTask<Void, Void, String>() {
|
|
@Override
|
|
protected void onPostExecute(String result) {
|
|
finishLoadProfile(result);
|
|
}
|
|
|
|
@Override
|
|
protected String doInBackground(Void... values) {
|
|
UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
|
|
if (user.iconPath == null || user.iconPath.equals("")) {
|
|
// Assign profile photo.
|
|
Utils.copyMeProfilePhoto(getActivity(), user);
|
|
}
|
|
return user.name;
|
|
}
|
|
}.execute();
|
|
}
|
|
|
|
private void finishLoadProfile(String profileName) {
|
|
if (getActivity() == null) return;
|
|
mMePreference.setTitle(getString(R.string.user_you, profileName));
|
|
int myUserId = UserHandle.myUserId();
|
|
Bitmap b = mUserManager.getUserIcon(myUserId);
|
|
if (b != null) {
|
|
mMePreference.setIcon(encircle(b));
|
|
mUserIcons.put(myUserId, b);
|
|
}
|
|
}
|
|
|
|
private boolean hasLockscreenSecurity() {
|
|
LockPatternUtils lpu = new LockPatternUtils(getActivity());
|
|
return lpu.isSecure(UserHandle.myUserId());
|
|
}
|
|
|
|
private void launchChooseLockscreen() {
|
|
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
|
|
chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
|
|
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
|
|
startActivityForResult(chooseLockIntent, REQUEST_CHOOSE_LOCK);
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
if (requestCode == REQUEST_CHOOSE_LOCK) {
|
|
if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) {
|
|
addUserNow(USER_TYPE_RESTRICTED_PROFILE);
|
|
}
|
|
} else {
|
|
mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
|
|
}
|
|
}
|
|
|
|
private void onAddUserClicked(int userType) {
|
|
synchronized (mUserLock) {
|
|
if (mRemovingUserId == -1 && !mAddingUser) {
|
|
switch (userType) {
|
|
case USER_TYPE_USER:
|
|
showDialog(DIALOG_ADD_USER);
|
|
break;
|
|
case USER_TYPE_RESTRICTED_PROFILE:
|
|
if (hasLockscreenSecurity()) {
|
|
addUserNow(USER_TYPE_RESTRICTED_PROFILE);
|
|
} else {
|
|
showDialog(DIALOG_NEED_LOCKSCREEN);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void onRemoveUserClicked(int userId) {
|
|
synchronized (mUserLock) {
|
|
if (mRemovingUserId == -1 && !mAddingUser) {
|
|
mRemovingUserId = userId;
|
|
showDialog(DIALOG_CONFIRM_REMOVE);
|
|
}
|
|
}
|
|
}
|
|
|
|
private UserInfo createRestrictedProfile() {
|
|
UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName);
|
|
Utils.assignDefaultPhoto(getActivity(), newUserInfo.id);
|
|
return newUserInfo;
|
|
}
|
|
|
|
private UserInfo createTrustedUser() {
|
|
UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0);
|
|
if (newUserInfo != null) {
|
|
Utils.assignDefaultPhoto(getActivity(), newUserInfo.id);
|
|
}
|
|
return newUserInfo;
|
|
}
|
|
|
|
private void onManageUserClicked(int userId, boolean newUser) {
|
|
mAddingUser = false;
|
|
if (userId == UserPreference.USERID_GUEST_DEFAULTS) {
|
|
Bundle extras = new Bundle();
|
|
extras.putBoolean(UserDetailsSettings.EXTRA_USER_GUEST, true);
|
|
((SettingsActivity) getActivity()).startPreferencePanel(
|
|
UserDetailsSettings.class.getName(),
|
|
extras, R.string.user_guest, null, null, 0);
|
|
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);
|
|
((SettingsActivity) getActivity()).startPreferencePanel(
|
|
RestrictedProfileSettings.class.getName(),
|
|
extras, R.string.user_restrictions_title, null,
|
|
null, 0);
|
|
} else if (info.id == UserHandle.myUserId()) {
|
|
// Jump to owner info panel
|
|
OwnerInfoSettings.show(this);
|
|
} else if (mUserCaps.mIsAdmin) {
|
|
Bundle extras = new Bundle();
|
|
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
|
|
((SettingsActivity) getActivity()).startPreferencePanel(
|
|
UserDetailsSettings.class.getName(),
|
|
extras,
|
|
-1, /* No title res id */
|
|
info.name, /* title */
|
|
null, /* resultTo */
|
|
0 /* resultRequestCode */);
|
|
}
|
|
}
|
|
|
|
private void onUserCreated(int userId) {
|
|
mAddedUserId = userId;
|
|
mAddingUser = false;
|
|
if (mUserManager.getUserInfo(userId).isRestricted()) {
|
|
showDialog(DIALOG_SETUP_PROFILE);
|
|
} else {
|
|
showDialog(DIALOG_SETUP_USER);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDialogShowing() {
|
|
super.onDialogShowing();
|
|
|
|
setOnDismissListener(this);
|
|
}
|
|
|
|
@Override
|
|
public Dialog onCreateDialog(int dialogId) {
|
|
Context context = getActivity();
|
|
if (context == null) return null;
|
|
switch (dialogId) {
|
|
case DIALOG_CONFIRM_REMOVE: {
|
|
Dialog dlg =
|
|
UserDialogs.createRemoveDialog(getActivity(), mRemovingUserId,
|
|
new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
removeUserNow();
|
|
}
|
|
}
|
|
);
|
|
return dlg;
|
|
}
|
|
case DIALOG_USER_CANNOT_MANAGE:
|
|
return new AlertDialog.Builder(context)
|
|
.setMessage(R.string.user_cannot_manage_message)
|
|
.setPositiveButton(android.R.string.ok, null)
|
|
.create();
|
|
case DIALOG_ADD_USER: {
|
|
final SharedPreferences preferences = getActivity().getPreferences(
|
|
Context.MODE_PRIVATE);
|
|
final boolean longMessageDisplayed = preferences.getBoolean(
|
|
KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, false);
|
|
final int messageResId = longMessageDisplayed
|
|
? R.string.user_add_user_message_short
|
|
: R.string.user_add_user_message_long;
|
|
final int userType = dialogId == DIALOG_ADD_USER
|
|
? USER_TYPE_USER : USER_TYPE_RESTRICTED_PROFILE;
|
|
Dialog dlg = new AlertDialog.Builder(context)
|
|
.setTitle(R.string.user_add_user_title)
|
|
.setMessage(messageResId)
|
|
.setPositiveButton(android.R.string.ok,
|
|
new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
addUserNow(userType);
|
|
if (!longMessageDisplayed) {
|
|
preferences.edit().putBoolean(
|
|
KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, true).apply();
|
|
}
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
.create();
|
|
return dlg;
|
|
}
|
|
case DIALOG_SETUP_USER: {
|
|
Dialog dlg = new AlertDialog.Builder(context)
|
|
.setTitle(R.string.user_setup_dialog_title)
|
|
.setMessage(R.string.user_setup_dialog_message)
|
|
.setPositiveButton(R.string.user_setup_button_setup_now,
|
|
new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
switchUserNow(mAddedUserId);
|
|
}
|
|
})
|
|
.setNegativeButton(R.string.user_setup_button_setup_later, null)
|
|
.create();
|
|
return dlg;
|
|
}
|
|
case DIALOG_SETUP_PROFILE: {
|
|
Dialog dlg = new AlertDialog.Builder(context)
|
|
.setMessage(R.string.user_setup_profile_dialog_message)
|
|
.setPositiveButton(android.R.string.ok,
|
|
new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
switchUserNow(mAddedUserId);
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
.create();
|
|
return dlg;
|
|
}
|
|
case DIALOG_CHOOSE_USER_TYPE: {
|
|
List<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();
|
|
HashMap<String,String> addUserItem = new HashMap<String,String>();
|
|
addUserItem.put(KEY_TITLE, getString(R.string.user_add_user_item_title));
|
|
addUserItem.put(KEY_SUMMARY, getString(R.string.user_add_user_item_summary));
|
|
HashMap<String,String> addProfileItem = new HashMap<String,String>();
|
|
addProfileItem.put(KEY_TITLE, getString(R.string.user_add_profile_item_title));
|
|
addProfileItem.put(KEY_SUMMARY, getString(R.string.user_add_profile_item_summary));
|
|
data.add(addUserItem);
|
|
data.add(addProfileItem);
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
SimpleAdapter adapter = new SimpleAdapter(builder.getContext(),
|
|
data, R.layout.two_line_list_item,
|
|
new String[] {KEY_TITLE, KEY_SUMMARY},
|
|
new int[] {R.id.title, R.id.summary});
|
|
builder.setTitle(R.string.user_add_user_type_title);
|
|
builder.setAdapter(adapter,
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
onAddUserClicked(which == 0
|
|
? USER_TYPE_USER
|
|
: USER_TYPE_RESTRICTED_PROFILE);
|
|
}
|
|
});
|
|
return builder.create();
|
|
}
|
|
case DIALOG_NEED_LOCKSCREEN: {
|
|
Dialog dlg = new AlertDialog.Builder(context)
|
|
.setMessage(R.string.user_need_lock_message)
|
|
.setPositiveButton(R.string.user_set_lock_button,
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
launchChooseLockscreen();
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
.create();
|
|
return dlg;
|
|
}
|
|
case DIALOG_CONFIRM_EXIT_GUEST: {
|
|
Dialog dlg = new AlertDialog.Builder(context)
|
|
.setTitle(R.string.user_exit_guest_confirm_title)
|
|
.setMessage(R.string.user_exit_guest_confirm_message)
|
|
.setPositiveButton(R.string.user_exit_guest_dialog_remove,
|
|
new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
exitGuest();
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
.create();
|
|
return dlg;
|
|
}
|
|
case DIALOG_USER_PROFILE_EDITOR: {
|
|
Dialog dlg = mEditUserInfoController.createDialog(
|
|
this,
|
|
mMePreference.getIcon(),
|
|
mMePreference.getTitle(),
|
|
R.string.profile_info_settings_title,
|
|
this /* callback */,
|
|
android.os.Process.myUserHandle());
|
|
return dlg;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private boolean emergencyInfoActivityPresent() {
|
|
Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO).setPackage("com.android.emergency");
|
|
List<ResolveInfo> infos = getContext().getPackageManager().queryIntentActivities(intent, 0);
|
|
if (infos == null || infos.isEmpty()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void removeUserNow() {
|
|
if (mRemovingUserId == UserHandle.myUserId()) {
|
|
removeThisUser();
|
|
} else {
|
|
new Thread() {
|
|
public void run() {
|
|
synchronized (mUserLock) {
|
|
mUserManager.removeUser(mRemovingUserId);
|
|
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
|
|
}
|
|
}
|
|
}.start();
|
|
}
|
|
}
|
|
|
|
private void removeThisUser() {
|
|
if (!mUserManager.canSwitchUsers()) {
|
|
Log.w(TAG, "Cannot remove current user when switching is disabled");
|
|
return;
|
|
}
|
|
try {
|
|
ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM);
|
|
getContext().getSystemService(UserManager.class).removeUser(UserHandle.myUserId());
|
|
} catch (RemoteException re) {
|
|
Log.e(TAG, "Unable to remove self user");
|
|
}
|
|
}
|
|
|
|
private void addUserNow(final int userType) {
|
|
synchronized (mUserLock) {
|
|
mAddingUser = true;
|
|
mAddingUserName = userType == USER_TYPE_USER ? getString(R.string.user_new_user_name)
|
|
: getString(R.string.user_new_profile_name);
|
|
//updateUserList();
|
|
new Thread() {
|
|
public void run() {
|
|
UserInfo user;
|
|
// Could take a few seconds
|
|
if (userType == USER_TYPE_USER) {
|
|
user = createTrustedUser();
|
|
} else {
|
|
user = createRestrictedProfile();
|
|
}
|
|
if (user == null) {
|
|
mAddingUser = false;
|
|
return;
|
|
}
|
|
synchronized (mUserLock) {
|
|
if (userType == USER_TYPE_USER) {
|
|
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
|
|
mHandler.sendMessage(mHandler.obtainMessage(
|
|
MESSAGE_SETUP_USER, user.id, user.serialNumber));
|
|
} else {
|
|
mHandler.sendMessage(mHandler.obtainMessage(
|
|
MESSAGE_CONFIG_USER, user.id, user.serialNumber));
|
|
}
|
|
}
|
|
}
|
|
}.start();
|
|
}
|
|
}
|
|
|
|
private void switchUserNow(int userId) {
|
|
try {
|
|
ActivityManagerNative.getDefault().switchUser(userId);
|
|
} catch (RemoteException re) {
|
|
// Nothing to do
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Erase the current user (guest) and switch to another user.
|
|
*/
|
|
private void exitGuest() {
|
|
// Just to be safe
|
|
if (!mUserCaps.mIsGuest) {
|
|
return;
|
|
}
|
|
removeThisUser();
|
|
}
|
|
|
|
private void updateUserList() {
|
|
if (getActivity() == null) return;
|
|
List<UserInfo> users = mUserManager.getUsers(true);
|
|
final Context context = getActivity();
|
|
|
|
final boolean voiceCapable = Utils.isVoiceCapable(context);
|
|
final ArrayList<Integer> missingIcons = new ArrayList<>();
|
|
final ArrayList<UserPreference> userPreferences = new ArrayList<>();
|
|
userPreferences.add(mMePreference);
|
|
|
|
for (UserInfo user : users) {
|
|
if (!user.supportsSwitchToByUser()) {
|
|
// Only users that can be switched to should show up here.
|
|
// e.g. Managed profiles appear under Accounts Settings instead
|
|
continue;
|
|
}
|
|
UserPreference pref;
|
|
if (user.id == UserHandle.myUserId()) {
|
|
pref = mMePreference;
|
|
} else if (user.isGuest()) {
|
|
// Skip over Guest. We add generic Guest settings after this loop
|
|
continue;
|
|
} else {
|
|
// 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.setOnPreferenceClickListener(this);
|
|
pref.setKey("id=" + user.id);
|
|
userPreferences.add(pref);
|
|
if (user.isAdmin()) {
|
|
pref.setSummary(R.string.user_admin);
|
|
}
|
|
pref.setTitle(user.name);
|
|
}
|
|
if (!isInitialized(user)) {
|
|
if (user.isRestricted()) {
|
|
pref.setSummary(R.string.user_summary_restricted_not_set_up);
|
|
} else {
|
|
pref.setSummary(R.string.user_summary_not_set_up);
|
|
}
|
|
} else if (user.isRestricted()) {
|
|
pref.setSummary(R.string.user_summary_restricted_profile);
|
|
}
|
|
if (user.iconPath != null) {
|
|
if (mUserIcons.get(user.id) == null) {
|
|
// Icon not loaded yet, print a placeholder
|
|
missingIcons.add(user.id);
|
|
pref.setIcon(getEncircledDefaultIcon());
|
|
} else {
|
|
setPhotoId(pref, user);
|
|
}
|
|
} else {
|
|
// Icon not available yet, print a placeholder
|
|
pref.setIcon(getEncircledDefaultIcon());
|
|
}
|
|
}
|
|
|
|
// Add a temporary entry for the user being created
|
|
if (mAddingUser) {
|
|
UserPreference pref = new UserPreference(getPrefContext(), null,
|
|
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());
|
|
userPreferences.add(pref);
|
|
pref.setDisabledByAdmin(
|
|
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
|
}
|
|
|
|
// Sort list of users by serialNum
|
|
Collections.sort(userPreferences, UserPreference.SERIAL_NUMBER_COMPARATOR);
|
|
|
|
getActivity().invalidateOptionsMenu();
|
|
|
|
// Load the icons
|
|
if (missingIcons.size() > 0) {
|
|
loadIconsAsync(missingIcons);
|
|
}
|
|
|
|
PreferenceScreen preferenceScreen = getPreferenceScreen();
|
|
preferenceScreen.removeAll();
|
|
|
|
// If profiles are supported, userPreferences will be added to the category labeled
|
|
// "User & Profiles", otherwise the category is skipped and elements are added directly
|
|
// to preferenceScreen
|
|
PreferenceGroup groupToAddUsers;
|
|
if (mUserCaps.mCanAddRestrictedProfile) {
|
|
mUserListCategory.removeAll();
|
|
mUserListCategory.setOrder(Preference.DEFAULT_ORDER);
|
|
preferenceScreen.addPreference(mUserListCategory);
|
|
groupToAddUsers = mUserListCategory;
|
|
} else {
|
|
groupToAddUsers = preferenceScreen;
|
|
}
|
|
for (UserPreference userPreference : userPreferences) {
|
|
userPreference.setOrder(Preference.DEFAULT_ORDER);
|
|
groupToAddUsers.addPreference(userPreference);
|
|
}
|
|
|
|
// Append Add user to the end of the list
|
|
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
|
|
Utils.isDeviceProvisioned(getActivity())) {
|
|
boolean moreUsers = mUserManager.canAddMoreUsers();
|
|
mAddUser.setOrder(Preference.DEFAULT_ORDER);
|
|
preferenceScreen.addPreference(mAddUser);
|
|
mAddUser.setEnabled(moreUsers && !mAddingUser);
|
|
if (!moreUsers) {
|
|
mAddUser.setSummary(getString(R.string.user_add_max_count, getMaxRealUsers()));
|
|
} else {
|
|
mAddUser.setSummary(null);
|
|
}
|
|
if (mAddUser.isEnabled()) {
|
|
mAddUser.setDisabledByAdmin(
|
|
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
|
}
|
|
}
|
|
if (mUserCaps.mIsAdmin &&
|
|
(!mUserCaps.mDisallowAddUser || mUserCaps.mDisallowAddUserSetByAdmin)) {
|
|
mLockScreenSettings.setOrder(Preference.DEFAULT_ORDER);
|
|
preferenceScreen.addPreference(mLockScreenSettings);
|
|
mAddUserWhenLocked.setChecked(Settings.Global.getInt(getContentResolver(),
|
|
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1);
|
|
mAddUserWhenLocked.setOnPreferenceChangeListener(this);
|
|
mAddUserWhenLocked.setDisabledByAdmin(
|
|
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
|
}
|
|
|
|
if (emergencyInfoActivityPresent()) {
|
|
mEmergencyInfoPreference.setOnPreferenceClickListener(this);
|
|
mEmergencyInfoPreference.setOrder(Preference.DEFAULT_ORDER);
|
|
preferenceScreen.addPreference(mEmergencyInfoPreference);
|
|
}
|
|
}
|
|
|
|
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) {
|
|
new AsyncTask<List<Integer>, Void, Void>() {
|
|
@Override
|
|
protected void onPostExecute(Void result) {
|
|
updateUserList();
|
|
}
|
|
|
|
@Override
|
|
protected Void doInBackground(List<Integer>... values) {
|
|
for (int userId : values[0]) {
|
|
Bitmap bitmap = mUserManager.getUserIcon(userId);
|
|
if (bitmap == null) {
|
|
bitmap = Utils.getDefaultUserIconAsBitmap(userId);
|
|
}
|
|
mUserIcons.append(userId, bitmap);
|
|
}
|
|
return null;
|
|
}
|
|
}.execute(missingIcons);
|
|
}
|
|
|
|
private Drawable getEncircledDefaultIcon() {
|
|
if (mDefaultIconDrawable == null) {
|
|
mDefaultIconDrawable = encircle(Utils.getDefaultUserIconAsBitmap(UserHandle.USER_NULL));
|
|
}
|
|
return mDefaultIconDrawable;
|
|
}
|
|
|
|
private void setPhotoId(Preference pref, UserInfo user) {
|
|
Bitmap bitmap = mUserIcons.get(user.id);
|
|
if (bitmap != null) {
|
|
pref.setIcon(encircle(bitmap));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onPreferenceClick(Preference pref) {
|
|
if (pref == mMePreference) {
|
|
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.isLinkedUser()) {
|
|
onManageUserClicked(UserHandle.myUserId(), false);
|
|
} else {
|
|
showDialog(DIALOG_USER_PROFILE_EDITOR);
|
|
}
|
|
} else if (pref instanceof UserPreference) {
|
|
int userId = ((UserPreference) pref).getUserId();
|
|
// Get the latest status of the user
|
|
UserInfo user = mUserManager.getUserInfo(userId);
|
|
if (!isInitialized(user)) {
|
|
mHandler.sendMessage(mHandler.obtainMessage(
|
|
MESSAGE_SETUP_USER, user.id, user.serialNumber));
|
|
}
|
|
} else if (pref == mAddUser) {
|
|
// If we allow both types, show a picker, otherwise directly go to
|
|
// flow for full user.
|
|
if (mUserCaps.mCanAddRestrictedProfile) {
|
|
showDialog(DIALOG_CHOOSE_USER_TYPE);
|
|
} else {
|
|
onAddUserClicked(USER_TYPE_USER);
|
|
}
|
|
} else if (pref == mEmergencyInfoPreference) {
|
|
Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO);
|
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
startActivity(intent);
|
|
}
|
|
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();
|
|
switch (v.getId()) {
|
|
case UserPreference.DELETE_ID:
|
|
final EnforcedAdmin removeDisallowedAdmin =
|
|
RestrictedLockUtils.checkIfRestrictionEnforced(getContext(),
|
|
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
|
|
if (removeDisallowedAdmin != null) {
|
|
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
|
|
removeDisallowedAdmin);
|
|
} else {
|
|
onRemoveUserClicked(userId);
|
|
}
|
|
break;
|
|
case UserPreference.SETTINGS_ID:
|
|
onManageUserClicked(userId, false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDismiss(DialogInterface dialog) {
|
|
synchronized (mUserLock) {
|
|
mRemovingUserId = -1;
|
|
updateUserList();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
if (preference == mAddUserWhenLocked) {
|
|
Boolean value = (Boolean) newValue;
|
|
Settings.Global.putInt(getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED,
|
|
value != null && value ? 1 : 0);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int getHelpResource() {
|
|
return R.string.help_url_users;
|
|
}
|
|
|
|
@Override
|
|
public void onPhotoChanged(Drawable photo) {
|
|
mMePreference.setIcon(photo);
|
|
}
|
|
|
|
@Override
|
|
public void onLabelChanged(CharSequence label) {
|
|
mMePreference.setTitle(label);
|
|
}
|
|
|
|
private static class UserCapabilities {
|
|
boolean mEnabled = true;
|
|
boolean mCanAddUser = true;
|
|
boolean mCanAddRestrictedProfile = true;
|
|
boolean mIsAdmin;
|
|
boolean mIsGuest;
|
|
boolean mCanAddGuest;
|
|
boolean mDisallowAddUser;
|
|
boolean mDisallowAddUserSetByAdmin;
|
|
EnforcedAdmin mEnforcedAdmin;
|
|
|
|
private UserCapabilities() {}
|
|
|
|
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;
|
|
}
|
|
|
|
final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId());
|
|
caps.mIsGuest = myUserInfo.isGuest();
|
|
caps.mIsAdmin = myUserInfo.isAdmin();
|
|
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
|
|
Context.DEVICE_POLICY_SERVICE);
|
|
// No restricted profiles for tablets with a device owner, or phones.
|
|
if (dpm.isDeviceManaged() || Utils.isVoiceCapable(context)) {
|
|
caps.mCanAddRestrictedProfile = false;
|
|
}
|
|
caps.updateAddUserCapabilities(context);
|
|
return caps;
|
|
}
|
|
|
|
public void updateAddUserCapabilities(Context context) {
|
|
mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
|
|
UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
|
final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
|
|
context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
|
mDisallowAddUserSetByAdmin =
|
|
mEnforcedAdmin != null && !hasBaseUserRestriction;
|
|
mDisallowAddUser =
|
|
(mEnforcedAdmin != null || hasBaseUserRestriction);
|
|
mCanAddUser = true;
|
|
if (!mIsAdmin || UserManager.getMaxSupportedUsers() < 2
|
|
|| !UserManager.supportsMultipleUsers()
|
|
|| mDisallowAddUser) {
|
|
mCanAddUser = false;
|
|
}
|
|
|
|
final boolean canAddUsersWhenLocked = mIsAdmin || Settings.Global.getInt(
|
|
context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
|
mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "UserCapabilities{" +
|
|
"mEnabled=" + mEnabled +
|
|
", mCanAddUser=" + mCanAddUser +
|
|
", mCanAddRestrictedProfile=" + mCanAddRestrictedProfile +
|
|
", mIsAdmin=" + mIsAdmin +
|
|
", mIsGuest=" + mIsGuest +
|
|
", mCanAddGuest=" + mCanAddGuest +
|
|
", mDisallowAddUser=" + mDisallowAddUser +
|
|
", mEnforcedAdmin=" + mEnforcedAdmin +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
|
|
|
private final Context mContext;
|
|
private final SummaryLoader mSummaryLoader;
|
|
|
|
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
|
|
mContext = context;
|
|
mSummaryLoader = summaryLoader;
|
|
}
|
|
|
|
@Override
|
|
public void setListening(boolean listening) {
|
|
if (listening) {
|
|
UserInfo info = mContext.getSystemService(UserManager.class).getUserInfo(
|
|
UserHandle.myUserId());
|
|
mSummaryLoader.setSummary(this, mContext.getString(R.string.user_summary,
|
|
info.name));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
|
|
= new SummaryLoader.SummaryProviderFactory() {
|
|
@Override
|
|
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
|
|
SummaryLoader summaryLoader) {
|
|
return new SummaryProvider(activity, summaryLoader);
|
|
}
|
|
};
|
|
|
|
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 || userCaps.mDisallowAddUserSetByAdmin) {
|
|
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;
|
|
}
|
|
};
|
|
|
|
}
|