blob: 3520a59d761fdfde5e353de4adb2f42f334141c9 [file] [log] [blame]
Amith Yamasanib810a0d2012-03-25 10:12:26 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings.users;
18
Amith Yamasanif162efe2013-04-29 10:43:05 -070019import android.app.Activity;
Sudheer Shankaacb1a612016-11-10 15:30:14 -080020import android.app.ActivityManager;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070021import android.app.AlertDialog;
22import android.app.Dialog;
Amith Yamasanif162efe2013-04-29 10:43:05 -070023import android.app.admin.DevicePolicyManager;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070024import android.content.BroadcastReceiver;
Amith Yamasani32630392012-08-10 19:31:39 -070025import android.content.Context;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070026import android.content.DialogInterface;
27import android.content.Intent;
28import android.content.IntentFilter;
Svetoslav Ganov263f7442012-09-25 16:11:16 -070029import android.content.SharedPreferences;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070030import android.content.pm.UserInfo;
Amith Yamasani5cdc9372012-11-14 16:23:40 -080031import android.content.res.Resources;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070032import android.graphics.Bitmap;
Fan Zhang4e540db2017-11-08 13:06:38 -080033import android.graphics.BitmapFactory;
Amith Yamasani48fa8572012-04-17 17:12:01 -070034import android.graphics.drawable.Drawable;
Fan Zhang4e540db2017-11-08 13:06:38 -080035import android.net.Uri;
Amith Yamasani32dccbc2012-09-13 18:06:49 -070036import android.os.AsyncTask;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070037import android.os.Bundle;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070038import android.os.Handler;
39import android.os.Message;
Amith Yamasaniae47ef42012-09-16 17:53:35 -070040import android.os.RemoteException;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070041import android.os.UserHandle;
Amith Yamasani32630392012-08-10 19:31:39 -070042import android.os.UserManager;
Fan Zhang4e540db2017-11-08 13:06:38 -080043import android.provider.ContactsContract;
Fan Zhang66b573a2016-10-06 16:33:13 -070044import android.provider.Settings.Global;
Fan Zhang4e540db2017-11-08 13:06:38 -080045import android.support.annotation.VisibleForTesting;
46import android.support.annotation.WorkerThread;
Jason Monk39b46742015-09-10 15:52:51 -040047import android.support.v7.preference.Preference;
48import android.support.v7.preference.Preference.OnPreferenceClickListener;
49import android.support.v7.preference.PreferenceGroup;
50import android.support.v7.preference.PreferenceScreen;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070051import android.util.Log;
Amith Yamasanif34a85d2012-09-17 18:31:45 -070052import android.util.SparseArray;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070053import android.view.Menu;
54import android.view.MenuInflater;
55import android.view.MenuItem;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070056import android.view.View;
57import android.view.View.OnClickListener;
Amith Yamasanifc8a3832013-04-23 11:44:59 -070058import android.widget.SimpleAdapter;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070059
Tamas Berghammer265d3c22016-06-22 15:34:45 +010060import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Fan Zhang4e540db2017-11-08 13:06:38 -080061import com.android.internal.util.UserIcons;
Amith Yamasanif162efe2013-04-29 10:43:05 -070062import com.android.internal.widget.LockPatternUtils;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070063import com.android.settings.R;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080064import com.android.settings.SettingsActivity;
Julia Reynoldsb9195d22014-06-11 16:18:16 -040065import com.android.settings.SettingsPreferenceFragment;
Amith Yamasaniae47ef42012-09-16 17:53:35 -070066import com.android.settings.Utils;
Doris Ling81f22e82017-03-23 11:10:14 -070067import com.android.settings.dashboard.SummaryLoader;
Maurice Lam2eb170c2017-04-28 16:18:47 -070068import com.android.settings.password.ChooseLockGeneric;
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -070069import com.android.settings.search.BaseSearchIndexProvider;
70import com.android.settings.search.Indexable;
71import com.android.settings.search.SearchIndexableRaw;
Sudheer Shanka682a9162016-01-13 22:10:18 +000072import com.android.settingslib.RestrictedLockUtils;
Maurice Lam2eb170c2017-04-28 16:18:47 -070073import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
Fan Zhang12b03b22017-10-29 13:57:29 -070074import com.android.settingslib.RestrictedPreference;
Wei Liu6e58d512015-08-24 17:29:04 -070075import com.android.settingslib.drawable.CircleFramedDrawable;
Amith Yamasanib810a0d2012-03-25 10:12:26 -070076
Fan Zhang4e540db2017-11-08 13:06:38 -080077import java.io.IOException;
78import java.io.InputStream;
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +010079import java.util.ArrayList;
Fyodor Kupolov55145092014-12-08 14:15:36 -080080import java.util.Collections;
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +010081import java.util.HashMap;
82import java.util.List;
83
Amith Yamasaniee398742014-07-24 14:13:36 -070084/**
85 * Screen that manages the list of users on the device.
86 * Guest user is an always visible entry, even if the guest is not currently
87 * active/created. It is meant for controlling properties of a guest user.
88 *
89 * The first one is always the current user.
90 * Owner is the primary user.
91 */
Julia Reynoldsb9195d22014-06-11 16:18:16 -040092public class UserSettings extends SettingsPreferenceFragment
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070093 implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -070094 EditUserInfoController.OnContentChangedCallback, Indexable {
Amith Yamasanib810a0d2012-03-25 10:12:26 -070095
Amith Yamasanidc6bfa62012-09-06 18:04:06 -070096 private static final String TAG = "UserSettings";
97
Amith Yamasanic861cf82012-10-02 14:51:46 -070098 /** UserId of the user being removed */
99 private static final String SAVE_REMOVING_USER = "removing_user";
100 /** UserId of the user that was just added */
101 private static final String SAVE_ADDING_USER = "adding_user";
102
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700103 private static final String KEY_USER_LIST = "user_list";
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700104 private static final String KEY_USER_ME = "user_me";
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700105 private static final String KEY_ADD_USER = "user_add";
Fan Zhang881d5792018-01-26 10:15:56 -0800106 private static final String KEY_ADD_USER_WHEN_LOCKED = "user_settings_add_users_when_locked";
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700107
Amith Yamasanicc395692013-04-11 18:21:07 -0700108 private static final int MENU_REMOVE_USER = Menu.FIRST;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700109
110 private static final int DIALOG_CONFIRM_REMOVE = 1;
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700111 private static final int DIALOG_ADD_USER = 2;
112 private static final int DIALOG_SETUP_USER = 3;
113 private static final int DIALOG_SETUP_PROFILE = 4;
Amith Yamasanicc395692013-04-11 18:21:07 -0700114 private static final int DIALOG_USER_CANNOT_MANAGE = 5;
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700115 private static final int DIALOG_CHOOSE_USER_TYPE = 6;
Amith Yamasanif162efe2013-04-29 10:43:05 -0700116 private static final int DIALOG_NEED_LOCKSCREEN = 7;
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700117 private static final int DIALOG_CONFIRM_EXIT_GUEST = 8;
Amith Yamasaniee398742014-07-24 14:13:36 -0700118 private static final int DIALOG_USER_PROFILE_EDITOR = 9;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700119
120 private static final int MESSAGE_UPDATE_LIST = 1;
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700121 private static final int MESSAGE_SETUP_USER = 2;
Amith Yamasanicc395692013-04-11 18:21:07 -0700122 private static final int MESSAGE_CONFIG_USER = 3;
123
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700124 private static final int USER_TYPE_USER = 1;
125 private static final int USER_TYPE_RESTRICTED_PROFILE = 2;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700126
Amith Yamasanif162efe2013-04-29 10:43:05 -0700127 private static final int REQUEST_CHOOSE_LOCK = 10;
128
Svetoslav Ganov263f7442012-09-25 16:11:16 -0700129 private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED =
130 "key_add_user_long_message_displayed";
131
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700132 private static final String KEY_TITLE = "title";
133 private static final String KEY_SUMMARY = "summary";
134
135 private PreferenceGroup mUserListCategory;
Fyodor Kupolov55145092014-12-08 14:15:36 -0800136 private UserPreference mMePreference;
Fan Zhang12b03b22017-10-29 13:57:29 -0700137 private RestrictedPreference mAddUser;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700138 private int mRemovingUserId = -1;
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700139 private int mAddedUserId = 0;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700140 private boolean mAddingUser;
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700141 private String mAddingUserName;
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700142 private UserCapabilities mUserCaps;
Fyodor Kupolov8c9120b2016-03-07 11:49:35 -0800143 private boolean mShouldUpdateUserList = true;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700144 private final Object mUserLock = new Object();
145 private UserManager mUserManager;
Fan Zhang4e540db2017-11-08 13:06:38 -0800146 private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
147 private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
Amith Yamasani8666b9e2012-09-27 14:50:13 -0700148
Fan Zhang881d5792018-01-26 10:15:56 -0800149 private EditUserInfoController mEditUserInfoController = new EditUserInfoController();
150 private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
151 private AutoSyncDataPreferenceController mAutoSyncDataPreferenceController;
152 private AutoSyncPersonalDataPreferenceController mAutoSyncPersonalDataPreferenceController;
153 private AutoSyncWorkDataPreferenceController mAutoSyncWorkDataPreferenceController;
Amith Yamasaniee398742014-07-24 14:13:36 -0700154
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700155 // A place to cache the generated default avatar
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100156 private Drawable mDefaultIconDrawable;
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700157
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700158 private Handler mHandler = new Handler() {
159 @Override
160 public void handleMessage(Message msg) {
161 switch (msg.what) {
162 case MESSAGE_UPDATE_LIST:
163 updateUserList();
164 break;
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700165 case MESSAGE_SETUP_USER:
166 onUserCreated(msg.arg1);
167 break;
Amith Yamasanicc395692013-04-11 18:21:07 -0700168 case MESSAGE_CONFIG_USER:
169 onManageUserClicked(msg.arg1, true);
170 break;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700171 }
172 }
173 };
174
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700175 private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700176 @Override
177 public void onReceive(Context context, Intent intent) {
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700178 if (intent.getAction().equals(Intent.ACTION_USER_REMOVED)) {
179 mRemovingUserId = -1;
180 } else if (intent.getAction().equals(Intent.ACTION_USER_INFO_CHANGED)) {
181 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
182 if (userHandle != -1) {
183 mUserIcons.remove(userHandle);
184 }
185 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700186 mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
187 }
188 };
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700189
190 @Override
Fan Zhang65076132016-08-08 10:25:13 -0700191 public int getMetricsCategory() {
Chris Wren9d1bfd12016-01-26 18:04:01 -0500192 return MetricsEvent.USER;
Chris Wren8a963ba2015-03-20 10:29:14 -0400193 }
194
195 @Override
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700196 public void onCreate(Bundle icicle) {
197 super.onCreate(icicle);
Fan Zhang881d5792018-01-26 10:15:56 -0800198 addPreferencesFromResource(R.xml.user_settings);
199 if (Global.getInt(getContext().getContentResolver(), Global.DEVICE_PROVISIONED, 0) == 0) {
200 getActivity().finish();
201 return;
202 }
203 final Context context = getActivity();
204 mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
205 context, KEY_ADD_USER_WHEN_LOCKED, getLifecycle());
206
207 mAutoSyncDataPreferenceController = new AutoSyncDataPreferenceController(context, this);
208 mAutoSyncPersonalDataPreferenceController =
209 new AutoSyncPersonalDataPreferenceController(context, this);
210 mAutoSyncWorkDataPreferenceController =
211 new AutoSyncWorkDataPreferenceController(context, this);
212
213 final PreferenceScreen screen = getPreferenceScreen();
214 mAddUserWhenLockedPreferenceController.displayPreference(screen);
215 mAutoSyncDataPreferenceController.displayPreference(screen);
216 mAutoSyncPersonalDataPreferenceController.displayPreference(screen);
217 mAutoSyncWorkDataPreferenceController.displayPreference(screen);
218 screen.findPreference(mAddUserWhenLockedPreferenceController.getPreferenceKey())
219 .setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
Amith Yamasani8666b9e2012-09-27 14:50:13 -0700220
Amith Yamasanic861cf82012-10-02 14:51:46 -0700221 if (icicle != null) {
222 if (icicle.containsKey(SAVE_ADDING_USER)) {
223 mAddedUserId = icicle.getInt(SAVE_ADDING_USER);
224 }
225 if (icicle.containsKey(SAVE_REMOVING_USER)) {
226 mRemovingUserId = icicle.getInt(SAVE_REMOVING_USER);
227 }
Amith Yamasaniee398742014-07-24 14:13:36 -0700228 mEditUserInfoController.onRestoreInstanceState(icicle);
Amith Yamasanic861cf82012-10-02 14:51:46 -0700229 }
Fan Zhang881d5792018-01-26 10:15:56 -0800230
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700231 mUserCaps = UserCapabilities.create(context);
Amith Yamasani0e43d322014-05-07 10:19:34 -0700232 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700233 if (!mUserCaps.mEnabled) {
Amith Yamasanicfb8d7f2014-03-26 14:46:47 -0700234 return;
235 }
Amith Yamasani0e43d322014-05-07 10:19:34 -0700236
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530237 final int myUserId = UserHandle.myUserId();
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530238
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700239 mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST);
Jason Monk39b46742015-09-10 15:52:51 -0400240 mMePreference = new UserPreference(getPrefContext(), null /* attrs */, myUserId,
Amith Yamasaniee398742014-07-24 14:13:36 -0700241 null /* settings icon handler */,
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700242 null /* delete icon handler */);
Amith Yamasanid4abdd22013-04-17 18:27:01 -0700243 mMePreference.setKey(KEY_USER_ME);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700244 mMePreference.setOnPreferenceClickListener(this);
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700245 if (mUserCaps.mIsAdmin) {
246 mMePreference.setSummary(R.string.user_admin);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700247 }
Fan Zhang12b03b22017-10-29 13:57:29 -0700248 mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
Yoshinori Hirano2ce843b2016-03-02 10:29:41 +0900249 mAddUser.useAdminDisabledSummary(false);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800250 // Determine if add user/profile button should be visible
Udam Saini679f7ad2016-03-25 10:47:00 -0700251 if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(getActivity())) {
Amith Yamasani0e43d322014-05-07 10:19:34 -0700252 mAddUser.setOnPreferenceClickListener(this);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800253 // change label to only mention user, if restricted profiles are not supported
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700254 if (!mUserCaps.mCanAddRestrictedProfile) {
Amith Yamasani0e43d322014-05-07 10:19:34 -0700255 mAddUser.setTitle(R.string.user_add_user_menu);
256 }
Amith Yamasani233592b2013-03-01 17:05:23 -0800257 }
Fan Zhang881d5792018-01-26 10:15:56 -0800258 final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700259 filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
Fyodor Kupolov8c9120b2016-03-07 11:49:35 -0800260 context.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, mHandler);
261 loadProfile();
262 updateUserList();
263 mShouldUpdateUserList = false;
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700264 }
265
266 @Override
267 public void onResume() {
268 super.onResume();
Amith Yamasanicfb8d7f2014-03-26 14:46:47 -0700269
Fan Zhang881d5792018-01-26 10:15:56 -0800270 if (!mUserCaps.mEnabled) {
271 return;
272 }
273 final PreferenceScreen screen = getPreferenceScreen();
274
275 if (mAutoSyncDataPreferenceController.isAvailable()) {
276 mAutoSyncDataPreferenceController.updateState(screen.findPreference(
277 mAutoSyncDataPreferenceController.getPreferenceKey()));
278 }
279 if (mAddUserWhenLockedPreferenceController.isAvailable()) {
280 mAddUserWhenLockedPreferenceController.updateState(screen.findPreference(
281 mAddUserWhenLockedPreferenceController.getPreferenceKey()));
282 }
283 if (mAutoSyncPersonalDataPreferenceController.isAvailable()) {
284 mAutoSyncPersonalDataPreferenceController.updateState(screen.findPreference(
285 mAutoSyncPersonalDataPreferenceController.getPreferenceKey()));
286 }
287 if (mAutoSyncWorkDataPreferenceController.isAvailable()) {
288 mAutoSyncWorkDataPreferenceController.updateState(screen.findPreference(
289 mAutoSyncWorkDataPreferenceController.getPreferenceKey()));
290 }
291
Fyodor Kupolov8c9120b2016-03-07 11:49:35 -0800292 if (mShouldUpdateUserList) {
Sudheer Shankaaa524ae2016-03-14 17:23:13 -0700293 mUserCaps.updateAddUserCapabilities(getActivity());
Fyodor Kupolov8c9120b2016-03-07 11:49:35 -0800294 loadProfile();
295 updateUserList();
296 }
297 }
298
299 @Override
300 public void onPause() {
301 mShouldUpdateUserList = true;
302 super.onPause();
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700303 }
304
305 @Override
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700306 public void onDestroy() {
307 super.onDestroy();
Amith Yamasanicfb8d7f2014-03-26 14:46:47 -0700308
Fan Zhang881d5792018-01-26 10:15:56 -0800309 if (!mUserCaps.mEnabled) {
310 return;
311 }
Amith Yamasanicfb8d7f2014-03-26 14:46:47 -0700312
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700313 getActivity().unregisterReceiver(mUserChangeReceiver);
314 }
315
316 @Override
Amith Yamasanic861cf82012-10-02 14:51:46 -0700317 public void onSaveInstanceState(Bundle outState) {
318 super.onSaveInstanceState(outState);
Amith Yamasaniee398742014-07-24 14:13:36 -0700319 mEditUserInfoController.onSaveInstanceState(outState);
Amith Yamasanic861cf82012-10-02 14:51:46 -0700320 outState.putInt(SAVE_ADDING_USER, mAddedUserId);
321 outState.putInt(SAVE_REMOVING_USER, mRemovingUserId);
322 }
323
324 @Override
Amith Yamasaniee398742014-07-24 14:13:36 -0700325 public void startActivityForResult(Intent intent, int requestCode) {
326 mEditUserInfoController.startingActivityForResult();
327 super.startActivityForResult(intent, requestCode);
328 }
329
330 @Override
Fan Zhang881d5792018-01-26 10:15:56 -0800331 public boolean onPreferenceTreeClick(Preference preference) {
332 if (mAutoSyncDataPreferenceController.handlePreferenceTreeClick(preference)) {
333 return true;
334 }
335 if (mAutoSyncPersonalDataPreferenceController.handlePreferenceTreeClick(preference)) {
336 return true;
337 }
338 if (mAutoSyncWorkDataPreferenceController.handlePreferenceTreeClick(preference)) {
339 return true;
340 }
341 return super.onPreferenceTreeClick(preference);
342 }
343
344 @Override
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700345 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Amith Yamasani247520c2014-07-25 12:52:29 -0700346 int pos = 0;
Fyodor Kupolov52ae0532016-02-24 15:54:10 -0800347 UserManager um = getContext().getSystemService(UserManager.class);
348 boolean allowRemoveUser = !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
349 boolean canSwitchUsers = um.canSwitchUsers();
350 if (!mUserCaps.mIsAdmin && allowRemoveUser && canSwitchUsers) {
Amith Yamasani1a634d32012-09-27 23:01:35 -0700351 String nickname = mUserManager.getUserName();
Amith Yamasani247520c2014-07-25 12:52:29 -0700352 MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
Amith Yamasani1a634d32012-09-27 23:01:35 -0700353 getResources().getString(R.string.user_remove_user_menu, nickname));
354 removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700355 }
Amith Yamasani38223dc2012-09-18 09:51:07 -0700356 super.onCreateOptionsMenu(menu, inflater);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700357 }
358
359 @Override
360 public boolean onOptionsItemSelected(MenuItem item) {
361 final int itemId = item.getItemId();
Amith Yamasanicc395692013-04-11 18:21:07 -0700362 if (itemId == MENU_REMOVE_USER) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700363 onRemoveUserClicked(UserHandle.myUserId());
364 return true;
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700365 } else {
366 return super.onOptionsItemSelected(item);
367 }
368 }
369
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700370 /**
371 * Loads profile information for the current user.
372 */
Amith Yamasani32dccbc2012-09-13 18:06:49 -0700373 private void loadProfile() {
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700374 if (mUserCaps.mIsGuest) {
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700375 // No need to load profile information
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100376 mMePreference.setIcon(getEncircledDefaultIcon());
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700377 mMePreference.setTitle(R.string.user_exit_guest_title);
378 return;
379 }
380
Amith Yamasani32dccbc2012-09-13 18:06:49 -0700381 new AsyncTask<Void, Void, String>() {
382 @Override
383 protected void onPostExecute(String result) {
384 finishLoadProfile(result);
385 }
386
387 @Override
388 protected String doInBackground(Void... values) {
389 UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
390 if (user.iconPath == null || user.iconPath.equals("")) {
Sudheer Shanka71caf692016-04-14 16:50:14 -0700391 // Assign profile photo.
Fan Zhang4e540db2017-11-08 13:06:38 -0800392 copyMeProfilePhoto(getActivity(), user);
Amith Yamasani32dccbc2012-09-13 18:06:49 -0700393 }
Amith Yamasani2d578ce2014-07-25 09:37:33 -0700394 return user.name;
Amith Yamasani32dccbc2012-09-13 18:06:49 -0700395 }
396 }.execute();
397 }
398
399 private void finishLoadProfile(String profileName) {
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700400 if (getActivity() == null) return;
401 mMePreference.setTitle(getString(R.string.user_you, profileName));
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700402 int myUserId = UserHandle.myUserId();
403 Bitmap b = mUserManager.getUserIcon(myUserId);
404 if (b != null) {
Amith Yamasani864e3b72013-03-27 12:27:01 -0700405 mMePreference.setIcon(encircle(b));
406 mUserIcons.put(myUserId, b);
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700407 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700408 }
409
Amith Yamasanif162efe2013-04-29 10:43:05 -0700410 private boolean hasLockscreenSecurity() {
411 LockPatternUtils lpu = new LockPatternUtils(getActivity());
Adrian Roos54375882015-04-16 17:11:22 -0700412 return lpu.isSecure(UserHandle.myUserId());
Amith Yamasanif162efe2013-04-29 10:43:05 -0700413 }
414
415 private void launchChooseLockscreen() {
416 Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
417 chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
418 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
419 startActivityForResult(chooseLockIntent, REQUEST_CHOOSE_LOCK);
420 }
421
422 @Override
423 public void onActivityResult(int requestCode, int resultCode, Intent data) {
424 super.onActivityResult(requestCode, resultCode, data);
425
426 if (requestCode == REQUEST_CHOOSE_LOCK) {
427 if (resultCode != Activity.RESULT_CANCELED && hasLockscreenSecurity()) {
428 addUserNow(USER_TYPE_RESTRICTED_PROFILE);
Amith Yamasanif162efe2013-04-29 10:43:05 -0700429 }
Amith Yamasaniee398742014-07-24 14:13:36 -0700430 } else {
431 mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
Amith Yamasanif162efe2013-04-29 10:43:05 -0700432 }
433 }
434
Amith Yamasanicc395692013-04-11 18:21:07 -0700435 private void onAddUserClicked(int userType) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700436 synchronized (mUserLock) {
437 if (mRemovingUserId == -1 && !mAddingUser) {
Amith Yamasanicc395692013-04-11 18:21:07 -0700438 switch (userType) {
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700439 case USER_TYPE_USER:
440 showDialog(DIALOG_ADD_USER);
Amith Yamasanicc395692013-04-11 18:21:07 -0700441 break;
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700442 case USER_TYPE_RESTRICTED_PROFILE:
Amith Yamasanif162efe2013-04-29 10:43:05 -0700443 if (hasLockscreenSecurity()) {
444 addUserNow(USER_TYPE_RESTRICTED_PROFILE);
445 } else {
446 showDialog(DIALOG_NEED_LOCKSCREEN);
447 }
Amith Yamasanicc395692013-04-11 18:21:07 -0700448 break;
449 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700450 }
451 }
452 }
453
454 private void onRemoveUserClicked(int userId) {
455 synchronized (mUserLock) {
456 if (mRemovingUserId == -1 && !mAddingUser) {
457 mRemovingUserId = userId;
458 showDialog(DIALOG_CONFIRM_REMOVE);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700459 }
460 }
461 }
462
Fyodor Kupolov9938f6f2015-08-26 17:24:09 -0700463 private UserInfo createRestrictedProfile() {
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700464 UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName);
Fan Zhang4e540db2017-11-08 13:06:38 -0800465 if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) {
jackqdyulei8164c642016-12-27 10:15:27 -0800466 return null;
467 }
Amith Yamasanicc395692013-04-11 18:21:07 -0700468 return newUserInfo;
469 }
470
471 private UserInfo createTrustedUser() {
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700472 UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0);
Fan Zhang4e540db2017-11-08 13:06:38 -0800473 if (newUserInfo != null && !assignDefaultPhoto(getActivity(), newUserInfo.id)) {
jackqdyulei8164c642016-12-27 10:15:27 -0800474 return null;
Amith Yamasanicc395692013-04-11 18:21:07 -0700475 }
476 return newUserInfo;
477 }
478
479 private void onManageUserClicked(int userId, boolean newUser) {
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700480 mAddingUser = false;
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530481 if (userId == UserPreference.USERID_GUEST_DEFAULTS) {
482 Bundle extras = new Bundle();
483 extras.putBoolean(UserDetailsSettings.EXTRA_USER_GUEST, true);
Fan Zhangc6ca3142017-02-14 15:02:35 -0800484 ((SettingsActivity) getActivity()).startPreferencePanel(this,
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530485 UserDetailsSettings.class.getName(),
486 extras, R.string.user_guest, null, null, 0);
487 return;
488 }
Amith Yamasanid4abdd22013-04-17 18:27:01 -0700489 UserInfo info = mUserManager.getUserInfo(userId);
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700490 if (info.isRestricted() && mUserCaps.mIsAdmin) {
Amith Yamasanid4abdd22013-04-17 18:27:01 -0700491 Bundle extras = new Bundle();
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700492 extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
493 extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
Fan Zhangc6ca3142017-02-14 15:02:35 -0800494 ((SettingsActivity) getActivity()).startPreferencePanel(this,
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700495 RestrictedProfileSettings.class.getName(),
Amith Yamasani7c4dfcc2013-05-22 12:51:30 -0700496 extras, R.string.user_restrictions_title, null,
Amith Yamasanid4abdd22013-04-17 18:27:01 -0700497 null, 0);
498 } else if (info.id == UserHandle.myUserId()) {
499 // Jump to owner info panel
Jason Monk3bcd76c2015-04-21 11:20:20 -0400500 OwnerInfoSettings.show(this);
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700501 } else if (mUserCaps.mIsAdmin) {
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530502 Bundle extras = new Bundle();
503 extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
Fan Zhangc6ca3142017-02-14 15:02:35 -0800504 ((SettingsActivity) getActivity()).startPreferencePanel(this,
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530505 UserDetailsSettings.class.getName(),
Amith Yamasani51c6dac2014-07-02 00:06:37 +0530506 extras,
507 -1, /* No title res id */
508 info.name, /* title */
509 null, /* resultTo */
510 0 /* resultRequestCode */);
Amith Yamasanicc395692013-04-11 18:21:07 -0700511 }
Amith Yamasani233592b2013-03-01 17:05:23 -0800512 }
513
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700514 private void onUserCreated(int userId) {
515 mAddedUserId = userId;
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700516 mAddingUser = false;
xiyuan.wangb6fa43d2017-10-20 17:59:58 +0800517 if (!isResumed()) {
518 Log.w(TAG, "Cannot show dialog after onPause");
519 return;
520 }
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700521 if (mUserManager.getUserInfo(userId).isRestricted()) {
522 showDialog(DIALOG_SETUP_PROFILE);
523 } else {
524 showDialog(DIALOG_SETUP_USER);
525 }
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700526 }
527
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700528 @Override
Amith Yamasanic861cf82012-10-02 14:51:46 -0700529 public void onDialogShowing() {
530 super.onDialogShowing();
531
532 setOnDismissListener(this);
533 }
534
535 @Override
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700536 public Dialog onCreateDialog(int dialogId) {
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700537 Context context = getActivity();
538 if (context == null) return null;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700539 switch (dialogId) {
Amith Yamasanic861cf82012-10-02 14:51:46 -0700540 case DIALOG_CONFIRM_REMOVE: {
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530541 Dialog dlg =
Fyodor Kupolovdbbd4fc2014-12-29 13:40:27 -0800542 UserDialogs.createRemoveDialog(getActivity(), mRemovingUserId,
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530543 new DialogInterface.OnClickListener() {
544 public void onClick(DialogInterface dialog, int which) {
545 removeUserNow();
546 }
547 }
548 );
Amith Yamasanic861cf82012-10-02 14:51:46 -0700549 return dlg;
550 }
Amith Yamasani1a634d32012-09-27 23:01:35 -0700551 case DIALOG_USER_CANNOT_MANAGE:
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700552 return new AlertDialog.Builder(context)
Amith Yamasani1a634d32012-09-27 23:01:35 -0700553 .setMessage(R.string.user_cannot_manage_message)
554 .setPositiveButton(android.R.string.ok, null)
555 .create();
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700556 case DIALOG_ADD_USER: {
Svetoslav Ganov263f7442012-09-25 16:11:16 -0700557 final SharedPreferences preferences = getActivity().getPreferences(
558 Context.MODE_PRIVATE);
559 final boolean longMessageDisplayed = preferences.getBoolean(
560 KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, false);
561 final int messageResId = longMessageDisplayed
562 ? R.string.user_add_user_message_short
563 : R.string.user_add_user_message_long;
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700564 final int userType = dialogId == DIALOG_ADD_USER
565 ? USER_TYPE_USER : USER_TYPE_RESTRICTED_PROFILE;
566 Dialog dlg = new AlertDialog.Builder(context)
567 .setTitle(R.string.user_add_user_title)
568 .setMessage(messageResId)
569 .setPositiveButton(android.R.string.ok,
570 new DialogInterface.OnClickListener() {
571 public void onClick(DialogInterface dialog, int which) {
572 addUserNow(userType);
573 if (!longMessageDisplayed) {
574 preferences.edit().putBoolean(
575 KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, true).apply();
576 }
Svetoslav Ganov263f7442012-09-25 16:11:16 -0700577 }
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700578 })
579 .setNegativeButton(android.R.string.cancel, null)
580 .create();
Amith Yamasanic861cf82012-10-02 14:51:46 -0700581 return dlg;
582 }
583 case DIALOG_SETUP_USER: {
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700584 Dialog dlg = new AlertDialog.Builder(context)
585 .setTitle(R.string.user_setup_dialog_title)
586 .setMessage(R.string.user_setup_dialog_message)
587 .setPositiveButton(R.string.user_setup_button_setup_now,
588 new DialogInterface.OnClickListener() {
589 public void onClick(DialogInterface dialog, int which) {
590 switchUserNow(mAddedUserId);
591 }
592 })
593 .setNegativeButton(R.string.user_setup_button_setup_later, null)
594 .create();
595 return dlg;
596 }
597 case DIALOG_SETUP_PROFILE: {
598 Dialog dlg = new AlertDialog.Builder(context)
599 .setMessage(R.string.user_setup_profile_dialog_message)
600 .setPositiveButton(android.R.string.ok,
601 new DialogInterface.OnClickListener() {
602 public void onClick(DialogInterface dialog, int which) {
603 switchUserNow(mAddedUserId);
604 }
605 })
606 .setNegativeButton(android.R.string.cancel, null)
607 .create();
608 return dlg;
609 }
610 case DIALOG_CHOOSE_USER_TYPE: {
611 List<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();
612 HashMap<String,String> addUserItem = new HashMap<String,String>();
613 addUserItem.put(KEY_TITLE, getString(R.string.user_add_user_item_title));
614 addUserItem.put(KEY_SUMMARY, getString(R.string.user_add_user_item_summary));
615 HashMap<String,String> addProfileItem = new HashMap<String,String>();
616 addProfileItem.put(KEY_TITLE, getString(R.string.user_add_profile_item_title));
617 addProfileItem.put(KEY_SUMMARY, getString(R.string.user_add_profile_item_summary));
618 data.add(addUserItem);
619 data.add(addProfileItem);
Amith Yamasanif3db0212014-12-02 17:21:23 -0800620 AlertDialog.Builder builder = new AlertDialog.Builder(context);
621 SimpleAdapter adapter = new SimpleAdapter(builder.getContext(),
622 data, R.layout.two_line_list_item,
623 new String[] {KEY_TITLE, KEY_SUMMARY},
624 new int[] {R.id.title, R.id.summary});
625 builder.setTitle(R.string.user_add_user_type_title);
626 builder.setAdapter(adapter,
627 new DialogInterface.OnClickListener() {
628 @Override
629 public void onClick(DialogInterface dialog, int which) {
630 onAddUserClicked(which == 0
631 ? USER_TYPE_USER
632 : USER_TYPE_RESTRICTED_PROFILE);
633 }
634 });
635 return builder.create();
Amith Yamasanic861cf82012-10-02 14:51:46 -0700636 }
Amith Yamasanif162efe2013-04-29 10:43:05 -0700637 case DIALOG_NEED_LOCKSCREEN: {
638 Dialog dlg = new AlertDialog.Builder(context)
639 .setMessage(R.string.user_need_lock_message)
640 .setPositiveButton(R.string.user_set_lock_button,
641 new DialogInterface.OnClickListener() {
642 @Override
643 public void onClick(DialogInterface dialog, int which) {
644 launchChooseLockscreen();
645 }
646 })
647 .setNegativeButton(android.R.string.cancel, null)
648 .create();
649 return dlg;
650 }
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700651 case DIALOG_CONFIRM_EXIT_GUEST: {
652 Dialog dlg = new AlertDialog.Builder(context)
653 .setTitle(R.string.user_exit_guest_confirm_title)
654 .setMessage(R.string.user_exit_guest_confirm_message)
Amith Yamasani94c01812014-08-18 16:42:43 -0700655 .setPositiveButton(R.string.user_exit_guest_dialog_remove,
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700656 new DialogInterface.OnClickListener() {
657 @Override
658 public void onClick(DialogInterface dialog, int which) {
659 exitGuest();
660 }
661 })
Amith Yamasani94c01812014-08-18 16:42:43 -0700662 .setNegativeButton(android.R.string.cancel, null)
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700663 .create();
664 return dlg;
665 }
Amith Yamasaniee398742014-07-24 14:13:36 -0700666 case DIALOG_USER_PROFILE_EDITOR: {
667 Dialog dlg = mEditUserInfoController.createDialog(
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700668 this,
Stephen Chen94d0b162016-10-05 18:06:03 -0700669 null,
Amith Yamasaniee398742014-07-24 14:13:36 -0700670 mMePreference.getTitle(),
671 R.string.profile_info_settings_title,
672 this /* callback */,
673 android.os.Process.myUserHandle());
674 return dlg;
675 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700676 default:
677 return null;
678 }
679 }
680
Fan Zhangd65184f2016-09-19 17:45:24 -0700681 @Override
682 public int getDialogMetricsCategory(int dialogId) {
683 switch (dialogId) {
684 case DIALOG_CONFIRM_REMOVE:
685 return MetricsEvent.DIALOG_USER_REMOVE;
686 case DIALOG_USER_CANNOT_MANAGE:
687 return MetricsEvent.DIALOG_USER_CANNOT_MANAGE;
688 case DIALOG_ADD_USER:
689 return MetricsEvent.DIALOG_USER_ADD;
690 case DIALOG_SETUP_USER:
691 return MetricsEvent.DIALOG_USER_SETUP;
692 case DIALOG_SETUP_PROFILE:
693 return MetricsEvent.DIALOG_USER_SETUP_PROFILE;
694 case DIALOG_CHOOSE_USER_TYPE:
695 return MetricsEvent.DIALOG_USER_CHOOSE_TYPE;
696 case DIALOG_NEED_LOCKSCREEN:
697 return MetricsEvent.DIALOG_USER_NEED_LOCKSCREEN;
698 case DIALOG_CONFIRM_EXIT_GUEST:
699 return MetricsEvent.DIALOG_USER_CONFIRM_EXIT_GUEST;
700 case DIALOG_USER_PROFILE_EDITOR:
701 return MetricsEvent.DIALOG_USER_EDIT_PROFILE;
702 default:
703 return 0;
704 }
705 }
706
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700707 private void removeUserNow() {
708 if (mRemovingUserId == UserHandle.myUserId()) {
709 removeThisUser();
710 } else {
711 new Thread() {
712 public void run() {
713 synchronized (mUserLock) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700714 mUserManager.removeUser(mRemovingUserId);
715 mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700716 }
717 }
718 }.start();
719 }
720 }
721
722 private void removeThisUser() {
Fyodor Kupolov52ae0532016-02-24 15:54:10 -0800723 if (!mUserManager.canSwitchUsers()) {
724 Log.w(TAG, "Cannot remove current user when switching is disabled");
725 return;
726 }
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700727 try {
Sudheer Shankaacb1a612016-11-10 15:30:14 -0800728 ActivityManager.getService().switchUser(UserHandle.USER_SYSTEM);
Fyodor Kupolov52ae0532016-02-24 15:54:10 -0800729 getContext().getSystemService(UserManager.class).removeUser(UserHandle.myUserId());
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700730 } catch (RemoteException re) {
731 Log.e(TAG, "Unable to remove self user");
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700732 }
733 }
734
Amith Yamasanicc395692013-04-11 18:21:07 -0700735 private void addUserNow(final int userType) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700736 synchronized (mUserLock) {
737 mAddingUser = true;
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700738 mAddingUserName = userType == USER_TYPE_USER ? getString(R.string.user_new_user_name)
739 : getString(R.string.user_new_profile_name);
Amith Yamasania98c4022013-04-19 15:27:52 -0700740 //updateUserList();
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700741 new Thread() {
742 public void run() {
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700743 UserInfo user;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700744 // Could take a few seconds
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700745 if (userType == USER_TYPE_USER) {
Amith Yamasanicc395692013-04-11 18:21:07 -0700746 user = createTrustedUser();
747 } else {
Fyodor Kupolov9938f6f2015-08-26 17:24:09 -0700748 user = createRestrictedProfile();
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700749 }
Sudheer Shankaaa524ae2016-03-14 17:23:13 -0700750 if (user == null) {
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700751 mAddingUser = false;
Sudheer Shankaaa524ae2016-03-14 17:23:13 -0700752 return;
753 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700754 synchronized (mUserLock) {
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700755 if (userType == USER_TYPE_USER) {
Amith Yamasania98c4022013-04-19 15:27:52 -0700756 mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
Alex Chauffae4c12018-01-30 14:22:50 +0000757 // Skip setting up user which results in user switching when the
758 // restriction is set.
759 if (!mUserCaps.mDisallowSwitchUser) {
760 mHandler.sendMessage(mHandler.obtainMessage(
761 MESSAGE_SETUP_USER, user.id, user.serialNumber));
762 }
Amith Yamasanicc395692013-04-11 18:21:07 -0700763 } else {
764 mHandler.sendMessage(mHandler.obtainMessage(
765 MESSAGE_CONFIG_USER, user.id, user.serialNumber));
766 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700767 }
768 }
769 }.start();
770 }
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700771 }
772
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700773 private void switchUserNow(int userId) {
774 try {
Sudheer Shankaacb1a612016-11-10 15:30:14 -0800775 ActivityManager.getService().switchUser(userId);
Amith Yamasaniae47ef42012-09-16 17:53:35 -0700776 } catch (RemoteException re) {
777 // Nothing to do
778 }
779 }
780
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700781 /**
782 * Erase the current user (guest) and switch to another user.
783 */
784 private void exitGuest() {
785 // Just to be safe
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700786 if (!mUserCaps.mIsGuest) {
Amith Yamasanic16b73e2014-07-17 19:13:51 -0700787 return;
788 }
789 removeThisUser();
790 }
791
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700792 private void updateUserList() {
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700793 if (getActivity() == null) return;
Amith Yamasanie278eda2012-09-20 22:44:48 -0700794 List<UserInfo> users = mUserManager.getUsers(true);
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530795 final Context context = getActivity();
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700796
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530797 final boolean voiceCapable = Utils.isVoiceCapable(context);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800798 final ArrayList<Integer> missingIcons = new ArrayList<>();
799 final ArrayList<UserPreference> userPreferences = new ArrayList<>();
Jason Monkc1cc9fe2017-06-30 11:29:40 -0400800 int guestId = UserPreference.USERID_GUEST_DEFAULTS;
Fyodor Kupolov55145092014-12-08 14:15:36 -0800801 userPreferences.add(mMePreference);
802
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700803 for (UserInfo user : users) {
Xiaohui Chen148ef772015-07-16 10:06:03 -0700804 if (!user.supportsSwitchToByUser()) {
805 // Only users that can be switched to should show up here.
806 // e.g. Managed profiles appear under Accounts Settings instead
Alexandra Gherghina83adb562014-07-31 19:30:41 +0100807 continue;
808 }
Fyodor Kupolov55145092014-12-08 14:15:36 -0800809 UserPreference pref;
Amith Yamasanic861cf82012-10-02 14:51:46 -0700810 if (user.id == UserHandle.myUserId()) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700811 pref = mMePreference;
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530812 } else if (user.isGuest()) {
813 // Skip over Guest. We add generic Guest settings after this loop
Jason Monkc1cc9fe2017-06-30 11:29:40 -0400814 guestId = user.id;
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530815 continue;
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700816 } else {
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530817 // With Telephony:
818 // Secondary user: Settings
819 // Guest: Settings
820 // Restricted Profile: There is no Restricted Profile
821 // Without Telephony:
822 // Secondary user: Delete
823 // Guest: Nothing
824 // Restricted Profile: Settings
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700825 final boolean showSettings = mUserCaps.mIsAdmin
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700826 && (voiceCapable || user.isRestricted());
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700827 final boolean showDelete = mUserCaps.mIsAdmin
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530828 && (!voiceCapable && !user.isRestricted() && !user.isGuest());
Jason Monk39b46742015-09-10 15:52:51 -0400829 pref = new UserPreference(getPrefContext(), null, user.id,
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530830 showSettings ? this : null,
831 showDelete ? this : null);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700832 pref.setKey("id=" + user.id);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800833 userPreferences.add(pref);
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700834 if (user.isAdmin()) {
835 pref.setSummary(R.string.user_admin);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700836 }
837 pref.setTitle(user.name);
Fyodor Kupolov77865ec2016-06-02 10:39:33 -0700838 pref.setSelectable(false);
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700839 }
Julia Reynolds8bda21a2016-04-29 08:42:01 -0400840 if (pref == null) {
841 continue;
842 }
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700843 if (!isInitialized(user)) {
Alexandra Gherghina423bafc2014-04-23 10:56:37 +0000844 if (user.isRestricted()) {
845 pref.setSummary(R.string.user_summary_restricted_not_set_up);
Alexandra Gherghina423bafc2014-04-23 10:56:37 +0000846 } else {
847 pref.setSummary(R.string.user_summary_not_set_up);
848 }
Alex Chauffae4c12018-01-30 14:22:50 +0000849 // Disallow setting up user which results in user switching when the restriction is
850 // set.
851 if (!mUserCaps.mDisallowSwitchUser) {
852 pref.setOnPreferenceClickListener(this);
853 pref.setSelectable(true);
854 }
Amith Yamasanifc8a3832013-04-23 11:44:59 -0700855 } else if (user.isRestricted()) {
856 pref.setSummary(R.string.user_summary_restricted_profile);
Amith Yamasani48fa8572012-04-17 17:12:01 -0700857 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700858 if (user.iconPath != null) {
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700859 if (mUserIcons.get(user.id) == null) {
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100860 // Icon not loaded yet, print a placeholder
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700861 missingIcons.add(user.id);
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100862 pref.setIcon(getEncircledDefaultIcon());
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700863 } else {
864 setPhotoId(pref, user);
865 }
Amith Yamasanif2663ab2014-08-11 17:17:29 -0700866 } else {
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100867 // Icon not available yet, print a placeholder
868 pref.setIcon(getEncircledDefaultIcon());
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700869 }
870 }
Amith Yamasani247520c2014-07-25 12:52:29 -0700871
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700872 // Add a temporary entry for the user being created
873 if (mAddingUser) {
Jason Monk39b46742015-09-10 15:52:51 -0400874 UserPreference pref = new UserPreference(getPrefContext(), null,
Fyodor Kupolov55145092014-12-08 14:15:36 -0800875 UserPreference.USERID_UNKNOWN, null, null);
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700876 pref.setEnabled(false);
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700877 pref.setTitle(mAddingUserName);
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100878 pref.setIcon(getEncircledDefaultIcon());
Fyodor Kupolov55145092014-12-08 14:15:36 -0800879 userPreferences.add(pref);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700880 }
Amith Yamasani9e6ac3d2014-06-30 15:31:37 +0530881
Fyodor Kupolov889bc3d2016-01-29 17:29:54 -0800882 // Check if Guest tile should be added.
Sudheer Shanka29737ad2016-02-11 17:17:21 +0000883 if (!mUserCaps.mIsGuest && (mUserCaps.mCanAddGuest ||
884 mUserCaps.mDisallowAddUserSetByAdmin)) {
885 // Add a virtual Guest user for guest defaults
Jason Monk39b46742015-09-10 15:52:51 -0400886 UserPreference pref = new UserPreference(getPrefContext(), null,
Fyodor Kupolov55145092014-12-08 14:15:36 -0800887 UserPreference.USERID_GUEST_DEFAULTS,
Xiaohui Chen64f530c2015-06-24 12:35:07 -0700888 mUserCaps.mIsAdmin && voiceCapable? this : null /* settings icon handler */,
Fyodor Kupolov55145092014-12-08 14:15:36 -0800889 null /* delete icon handler */);
890 pref.setTitle(R.string.user_guest);
891 pref.setIcon(getEncircledDefaultIcon());
Fyodor Kupolov55145092014-12-08 14:15:36 -0800892 userPreferences.add(pref);
Alex Chauffae4c12018-01-30 14:22:50 +0000893 if (mUserCaps.mDisallowAddUser) {
894 pref.setDisabledByAdmin(mUserCaps.mEnforcedAdmin);
895 } else if (mUserCaps.mDisallowSwitchUser) {
896 pref.setDisabledByAdmin(RestrictedLockUtils.getDeviceOwner(context));
897 } else {
898 pref.setDisabledByAdmin(null);
899 }
Jason Monkc1cc9fe2017-06-30 11:29:40 -0400900 int finalGuestId = guestId;
901 pref.setOnPreferenceClickListener(preference -> {
902 int id = finalGuestId;
903 if (id == UserPreference.USERID_GUEST_DEFAULTS) {
904 UserInfo guest = mUserManager.createGuest(
905 getContext(), preference.getTitle().toString());
906 if (guest != null) {
907 id = guest.id;
908 }
909 }
910 try {
911 ActivityManager.getService().switchUser(id);
912 } catch (RemoteException e) {
913 e.rethrowFromSystemServer();
914 }
915 return true;
916 });
Fyodor Kupolov55145092014-12-08 14:15:36 -0800917 }
918
919 // Sort list of users by serialNum
920 Collections.sort(userPreferences, UserPreference.SERIAL_NUMBER_COMPARATOR);
921
922 getActivity().invalidateOptionsMenu();
923
924 // Load the icons
925 if (missingIcons.size() > 0) {
926 loadIconsAsync(missingIcons);
927 }
928
Fan Zhang881d5792018-01-26 10:15:56 -0800929 // Remove everything from mUserListCategory and add new users.
930 mUserListCategory.removeAll();
931 // If profiles are supported, mUserListCategory will have a special title
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -0700932 if (mUserCaps.mCanAddRestrictedProfile) {
Fan Zhang881d5792018-01-26 10:15:56 -0800933 mUserListCategory.setTitle(R.string.user_list_title);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800934 } else {
Fan Zhang881d5792018-01-26 10:15:56 -0800935 mUserListCategory.setTitle(null);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800936 }
Fan Zhang881d5792018-01-26 10:15:56 -0800937
Fyodor Kupolov55145092014-12-08 14:15:36 -0800938 for (UserPreference userPreference : userPreferences) {
939 userPreference.setOrder(Preference.DEFAULT_ORDER);
Fan Zhang881d5792018-01-26 10:15:56 -0800940 mUserListCategory.addPreference(userPreference);
Fyodor Kupolov55145092014-12-08 14:15:36 -0800941 }
942
943 // Append Add user to the end of the list
Udam Saini679f7ad2016-03-25 10:47:00 -0700944 if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
945 Utils.isDeviceProvisioned(getActivity())) {
Fyodor Kupolov55145092014-12-08 14:15:36 -0800946 boolean moreUsers = mUserManager.canAddMoreUsers();
Fyodor Kupolovfe6cb6d2016-03-28 15:10:19 -0700947 mAddUser.setEnabled(moreUsers && !mAddingUser);
Fyodor Kupolova7a7bfe2015-05-08 15:54:38 -0700948 if (!moreUsers) {
949 mAddUser.setSummary(getString(R.string.user_add_max_count, getMaxRealUsers()));
950 } else {
951 mAddUser.setSummary(null);
952 }
Sudheer Shanka682a9162016-01-13 22:10:18 +0000953 if (mAddUser.isEnabled()) {
954 mAddUser.setDisabledByAdmin(
955 mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
956 }
Fyodor Kupolov55145092014-12-08 14:15:36 -0800957 }
Doris Ling86e1df92016-10-31 17:08:04 -0700958
Fyodor Kupolov55145092014-12-08 14:15:36 -0800959 }
960
Fyodor Kupolova7a7bfe2015-05-08 15:54:38 -0700961 private int getMaxRealUsers() {
962 // guest is not counted against getMaxSupportedUsers() number
963 final int maxUsersAndGuest = UserManager.getMaxSupportedUsers() + 1;
964 final List<UserInfo> users = mUserManager.getUsers();
965 // managed profiles are counted against getMaxSupportedUsers()
966 int managedProfiles = 0;
967 for (UserInfo user : users) {
968 if (user.isManagedProfile()) {
969 managedProfiles++;
970 }
971 }
972 return maxUsersAndGuest - managedProfiles;
973 }
974
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700975 private void loadIconsAsync(List<Integer> missingIcons) {
976 new AsyncTask<List<Integer>, Void, Void>() {
977 @Override
978 protected void onPostExecute(Void result) {
979 updateUserList();
980 }
981
982 @Override
983 protected Void doInBackground(List<Integer>... values) {
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700984 for (int userId : values[0]) {
985 Bitmap bitmap = mUserManager.getUserIcon(userId);
Amith Yamasanif2663ab2014-08-11 17:17:29 -0700986 if (bitmap == null) {
Tony Mak0ba8f512017-11-23 16:58:20 +0800987 bitmap = getDefaultUserIconAsBitmap(getContext().getResources(), userId);
Amith Yamasanif2663ab2014-08-11 17:17:29 -0700988 }
Amith Yamasani864e3b72013-03-27 12:27:01 -0700989 mUserIcons.append(userId, bitmap);
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700990 }
991 return null;
992 }
993 }.execute(missingIcons);
Amith Yamasanif34a85d2012-09-17 18:31:45 -0700994 }
Amith Yamasani5cdc9372012-11-14 16:23:40 -0800995
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +0100996 private Drawable getEncircledDefaultIcon() {
997 if (mDefaultIconDrawable == null) {
Tony Mak0ba8f512017-11-23 16:58:20 +0800998 mDefaultIconDrawable = encircle(
999 getDefaultUserIconAsBitmap(getContext().getResources(), UserHandle.USER_NULL));
Amith Yamasanic16b73e2014-07-17 19:13:51 -07001000 }
Alexandra Gherghinabc6e78f2014-09-03 10:22:09 +01001001 return mDefaultIconDrawable;
Amith Yamasanic16b73e2014-07-17 19:13:51 -07001002 }
1003
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001004 private void setPhotoId(Preference pref, UserInfo user) {
Amith Yamasanid4abdd22013-04-17 18:27:01 -07001005 Bitmap bitmap = mUserIcons.get(user.id);
Amith Yamasani864e3b72013-03-27 12:27:01 -07001006 if (bitmap != null) {
1007 pref.setIcon(encircle(bitmap));
Amith Yamasanie940dac2012-09-17 10:21:27 -07001008 }
Amith Yamasani48fa8572012-04-17 17:12:01 -07001009 }
1010
Amith Yamasanib810a0d2012-03-25 10:12:26 -07001011 @Override
1012 public boolean onPreferenceClick(Preference pref) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001013 if (pref == mMePreference) {
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001014 if (mUserCaps.mIsGuest) {
Amith Yamasanic16b73e2014-07-17 19:13:51 -07001015 showDialog(DIALOG_CONFIRM_EXIT_GUEST);
1016 return true;
1017 }
Amith Yamasanid4abdd22013-04-17 18:27:01 -07001018 // If this is a limited user, launch the user info settings instead of profile editor
1019 if (mUserManager.isLinkedUser()) {
1020 onManageUserClicked(UserHandle.myUserId(), false);
1021 } else {
Amith Yamasaniee398742014-07-24 14:13:36 -07001022 showDialog(DIALOG_USER_PROFILE_EDITOR);
Amith Yamasanid4abdd22013-04-17 18:27:01 -07001023 }
Amith Yamasani1a634d32012-09-27 23:01:35 -07001024 } else if (pref instanceof UserPreference) {
1025 int userId = ((UserPreference) pref).getUserId();
Fyodor Kupolov889bc3d2016-01-29 17:29:54 -08001026 // Get the latest status of the user
1027 UserInfo user = mUserManager.getUserInfo(userId);
1028 if (!isInitialized(user)) {
1029 mHandler.sendMessage(mHandler.obtainMessage(
1030 MESSAGE_SETUP_USER, user.id, user.serialNumber));
Amith Yamasani1a634d32012-09-27 23:01:35 -07001031 }
Amith Yamasanifc8a3832013-04-23 11:44:59 -07001032 } else if (pref == mAddUser) {
Amith Yamasani0e43d322014-05-07 10:19:34 -07001033 // If we allow both types, show a picker, otherwise directly go to
1034 // flow for full user.
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001035 if (mUserCaps.mCanAddRestrictedProfile) {
Amith Yamasani0e43d322014-05-07 10:19:34 -07001036 showDialog(DIALOG_CHOOSE_USER_TYPE);
1037 } else {
1038 onAddUserClicked(USER_TYPE_USER);
1039 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001040 }
1041 return false;
1042 }
1043
Amith Yamasani1a634d32012-09-27 23:01:35 -07001044 private boolean isInitialized(UserInfo user) {
1045 return (user.flags & UserInfo.FLAG_INITIALIZED) != 0;
1046 }
1047
Amith Yamasani864e3b72013-03-27 12:27:01 -07001048 private Drawable encircle(Bitmap icon) {
1049 Drawable circled = CircleFramedDrawable.getInstance(getActivity(), icon);
1050 return circled;
1051 }
1052
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001053 @Override
1054 public void onClick(View v) {
1055 if (v.getTag() instanceof UserPreference) {
1056 int userId = ((UserPreference) v.getTag()).getUserId();
Amith Yamasani233592b2013-03-01 17:05:23 -08001057 switch (v.getId()) {
1058 case UserPreference.DELETE_ID:
Sudheer Shankab5c92142016-03-22 17:24:07 -07001059 final EnforcedAdmin removeDisallowedAdmin =
1060 RestrictedLockUtils.checkIfRestrictionEnforced(getContext(),
1061 UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId());
1062 if (removeDisallowedAdmin != null) {
1063 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
1064 removeDisallowedAdmin);
1065 } else {
1066 onRemoveUserClicked(userId);
1067 }
Amith Yamasani233592b2013-03-01 17:05:23 -08001068 break;
1069 case UserPreference.SETTINGS_ID:
Amith Yamasanicc395692013-04-11 18:21:07 -07001070 onManageUserClicked(userId, false);
Amith Yamasani233592b2013-03-01 17:05:23 -08001071 break;
1072 }
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001073 }
1074 }
1075
1076 @Override
1077 public void onDismiss(DialogInterface dialog) {
1078 synchronized (mUserLock) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001079 mRemovingUserId = -1;
Amith Yamasanic861cf82012-10-02 14:51:46 -07001080 updateUserList();
Amith Yamasanidc6bfa62012-09-06 18:04:06 -07001081 }
1082 }
1083
1084 @Override
Amith Yamasani38223dc2012-09-18 09:51:07 -07001085 public int getHelpResource() {
1086 return R.string.help_url_users;
1087 }
Amith Yamasaniee398742014-07-24 14:13:36 -07001088
1089 @Override
1090 public void onPhotoChanged(Drawable photo) {
1091 mMePreference.setIcon(photo);
1092 }
1093
1094 @Override
1095 public void onLabelChanged(CharSequence label) {
1096 mMePreference.setTitle(label);
1097 }
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001098
Fan Zhang4e540db2017-11-08 13:06:38 -08001099 /**
1100 * Returns a default user icon (as a {@link Bitmap}) for the given user.
1101 *
1102 * Note that for guest users, you should pass in {@code UserHandle.USER_NULL}.
Tony Mak0ba8f512017-11-23 16:58:20 +08001103 * @param resources resources object to fetch the user icon.
Fan Zhang4e540db2017-11-08 13:06:38 -08001104 * @param userId the user id or {@code UserHandle.USER_NULL} for a non-user specific icon
1105 */
Tony Mak0ba8f512017-11-23 16:58:20 +08001106 private static Bitmap getDefaultUserIconAsBitmap(Resources resources, int userId) {
Fan Zhang4e540db2017-11-08 13:06:38 -08001107 Bitmap bitmap = null;
1108 // Try finding the corresponding bitmap in the dark bitmap cache
1109 bitmap = sDarkDefaultUserBitmapCache.get(userId);
1110 if (bitmap == null) {
Tony Mak0ba8f512017-11-23 16:58:20 +08001111 bitmap = UserIcons.convertToBitmap(
1112 UserIcons.getDefaultUserIcon(resources, userId, false));
Fan Zhang4e540db2017-11-08 13:06:38 -08001113 // Save it to cache
1114 sDarkDefaultUserBitmapCache.put(userId, bitmap);
1115 }
1116 return bitmap;
1117 }
1118
1119 /**
1120 * Assign the default photo to user with {@paramref userId}
1121 * @param context used to get the {@link UserManager}
1122 * @param userId used to get the icon bitmap
1123 * @return true if assign photo successfully, false if failed
1124 */
1125 @VisibleForTesting
1126 static boolean assignDefaultPhoto(Context context, int userId) {
1127 if (context == null) {
1128 return false;
1129 }
1130 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
Tony Mak0ba8f512017-11-23 16:58:20 +08001131 Bitmap bitmap = getDefaultUserIconAsBitmap(context.getResources(), userId);
Fan Zhang4e540db2017-11-08 13:06:38 -08001132 um.setUserIcon(userId, bitmap);
1133
1134 return true;
1135 }
1136
1137 @WorkerThread
1138 static void copyMeProfilePhoto(Context context, UserInfo user) {
1139 Uri contactUri = ContactsContract.Profile.CONTENT_URI;
1140
1141 int userId = user != null ? user.id : UserHandle.myUserId();
1142
1143 InputStream avatarDataStream = ContactsContract.Contacts.openContactPhotoInputStream(
1144 context.getContentResolver(),
1145 contactUri, true);
1146 // If there's no profile photo, assign a default avatar
1147 if (avatarDataStream == null) {
1148 assignDefaultPhoto(context, userId);
1149 return;
1150 }
1151
1152 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
1153 Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
1154 um.setUserIcon(userId, icon);
1155 try {
1156 avatarDataStream.close();
1157 } catch (IOException ioe) { }
1158 }
1159
Doris Ling81f22e82017-03-23 11:10:14 -07001160 private static class SummaryProvider implements SummaryLoader.SummaryProvider {
1161
1162 private final Context mContext;
1163 private final SummaryLoader mSummaryLoader;
1164
1165 public SummaryProvider(Context context, SummaryLoader summaryLoader) {
1166 mContext = context;
1167 mSummaryLoader = summaryLoader;
1168 }
1169
1170 @Override
1171 public void setListening(boolean listening) {
1172 if (listening) {
1173 UserInfo info = mContext.getSystemService(UserManager.class).getUserInfo(
1174 UserHandle.myUserId());
1175 mSummaryLoader.setSummary(this, mContext.getString(R.string.users_summary,
1176 info.name));
1177 }
1178 }
1179 }
1180
1181 public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
1182 new SummaryLoader.SummaryProviderFactory() {
1183 @Override
1184 public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
1185 SummaryLoader summaryLoader) {
1186 return new SummaryProvider(activity, summaryLoader);
1187 }
1188 };
1189
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001190 public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
1191 new BaseSearchIndexProvider() {
1192 @Override
1193 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
1194 boolean enabled) {
1195 final List<SearchIndexableRaw> result = new ArrayList<>();
1196 final UserCapabilities userCaps = UserCapabilities.create(context);
1197 if (!userCaps.mEnabled) {
1198 return result;
1199 }
1200 final Resources res = context.getResources();
1201 SearchIndexableRaw data = new SearchIndexableRaw(context);
1202 data.title = res.getString(R.string.user_settings_title);
Fan Zhang7d5c9ac2017-11-16 09:56:03 -08001203 data.key = "users_settings";
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001204 data.screenTitle = res.getString(R.string.user_settings_title);
1205 result.add(data);
1206
Sudheer Shanka29737ad2016-02-11 17:17:21 +00001207 if (userCaps.mCanAddUser || userCaps.mDisallowAddUserSetByAdmin) {
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001208 data = new SearchIndexableRaw(context);
1209 data.title = res.getString(userCaps.mCanAddRestrictedProfile ?
1210 R.string.user_add_user_or_profile_menu
1211 : R.string.user_add_user_menu);
1212 data.screenTitle = res.getString(R.string.user_settings_title);
Fan Zhang7d5c9ac2017-11-16 09:56:03 -08001213 data.key = "user_settings_add_users";
Fyodor Kupolovc9a95ef2015-05-15 17:16:15 -07001214 result.add(data);
1215 }
1216 return result;
1217 }
1218 };
1219
Amith Yamasanib810a0d2012-03-25 10:12:26 -07001220}