UserSwitcherController.java revision c06fbb12984a3d3e4c80ab9f819841acae5b0133
100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/* 200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Copyright (C) 2014 The Android Open Source Project 300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * you may not use this file except in compliance with the License. 600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * You may obtain a copy of the License at 700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * http://www.apache.org/licenses/LICENSE-2.0 900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 1000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Unless required by applicable law or agreed to in writing, software 1100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 1200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * See the License for the specific language governing permissions and 1400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * limitations under the License 1500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 1600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 1700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospackage com.android.systemui.statusbar.policy; 1800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 1900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManager; 2000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManagerNative; 215005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.app.Dialog; 22f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.Notification; 23f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.NotificationManager; 24f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.PendingIntent; 2500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.BroadcastReceiver; 2600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Context; 275005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.content.DialogInterface; 2800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Intent; 2900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.IntentFilter; 3000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.pm.UserInfo; 312daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.database.ContentObserver; 3200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.graphics.Bitmap; 33ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roosimport android.graphics.drawable.Drawable; 3400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.AsyncTask; 35cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xiaimport android.os.Build; 362daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.os.Handler; 3700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.RemoteException; 38e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.os.UserHandle; 3900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.UserManager; 402daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.provider.Settings; 4100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log; 42e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray; 4388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseBooleanArray; 4488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseIntArray; 4500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View; 4600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup; 4700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter; 4800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 49457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wrenimport com.android.internal.logging.MetricsLogger; 5064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 5164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.BitmapHelper; 5264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver; 5364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R; 5464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.QSTile; 5564d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView; 5664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog; 5764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina 5800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor; 5900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter; 6000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference; 6100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList; 6200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List; 6300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 6400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/** 6500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Keeps a list of all users on the device for user switching. 6600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 6700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospublic class UserSwitcherController { 6800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 6900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private static final String TAG = "UserSwitcherController"; 705005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private static final boolean DEBUG = false; 712daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = 722daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk "lockscreenSimpleUserSwitcher"; 73f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST"; 74860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String ACTION_LOGOUT_USER = "com.android.systemui.LOGOUT_USER"; 7588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000; 7600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 77d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final int ID_REMOVE_GUEST = 1010; 78860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final int ID_LOGOUT_USER = 1011; 79d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String TAG_REMOVE_GUEST = "remove_guest"; 80860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String TAG_LOGOUT_USER = "logout_user"; 81860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 82d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; 83d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani 8400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final Context mContext; 8500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final UserManager mUserManager; 8600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); 875005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final GuestResumeSessionReceiver mGuestResumeSessionReceiver 885005244f10442e75c1f48973fdddce5facf3f360Adrian Roos = new GuestResumeSessionReceiver(); 89ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor mKeyguardMonitor; 9088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Handler mHandler; 9100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 9200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private ArrayList<UserRecord> mUsers = new ArrayList<>(); 935005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private Dialog mExitGuestDialog; 940c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private Dialog mAddUserDialog; 957cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen private int mLastNonGuestUser = UserHandle.USER_SYSTEM; 96ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mSimpleUserSwitcher; 97ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mAddUsersWhenLocked; 9888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private boolean mPauseRefreshUsers; 9988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); 10000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 10188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, 10288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos Handler handler) { 10300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mContext = context; 1045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestResumeSessionReceiver.register(context); 105ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mKeyguardMonitor = keyguardMonitor; 10688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler = handler; 10700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserManager = UserManager.get(context); 10800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos IntentFilter filter = new IntentFilter(); 10900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_ADDED); 11000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_REMOVED); 11100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 11200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 113e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos filter.addAction(Intent.ACTION_USER_STOPPING); 1147cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 115e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos null /* permission */, null /* scheduler */); 1162daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 117d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter = new IntentFilter(); 118d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter.addAction(ACTION_REMOVE_GUEST); 119860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen filter.addAction(ACTION_LOGOUT_USER); 1205891a346abbde5bfe95a52633d05533406cc6a2eAmith Yamasani mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 121d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani PERMISSION_SELF, null /* scheduler */); 122ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1232daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mContext.getContentResolver().registerContentObserver( 1242daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, 125ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 126ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mContext.getContentResolver().registerContentObserver( 127ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, 128ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 129ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Fetch initial values. 130ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver.onChange(false); 131ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 132ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos keyguardMonitor.addCallback(mCallback); 1332daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 134e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(UserHandle.USER_NULL); 13500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 13600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 137e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos /** 138e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * Refreshes users from UserManager. 139e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 140e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * The pictures are only loaded if they have not been loaded yet. 141e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 142e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * @param forcePictureLoadForId forces the picture of the given user to be reloaded. 143e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos */ 14495ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani @SuppressWarnings("unchecked") 145e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void refreshUsers(int forcePictureLoadForId) { 14688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")"); 14788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (forcePictureLoadForId != UserHandle.USER_NULL) { 14888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.put(forcePictureLoadForId, true); 14988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 15088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 15188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (mPauseRefreshUsers) { 15288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos return; 15388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 154c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos 155c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); 156c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos final int N = mUsers.size(); 157c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos for (int i = 0; i < N; i++) { 158c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos UserRecord r = mUsers.get(i); 15988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (r == null || r.picture == null || 16088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos r.info == null || mForcePictureLoadForUserId.get(r.info.id)) { 161c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos continue; 162e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 163c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos bitmaps.put(r.info.id, r.picture); 164e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 16588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.clear(); 166e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 167ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final boolean addUsersWhenLocked = mAddUsersWhenLocked; 168e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { 169e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos @SuppressWarnings("unchecked") 17000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 171e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { 172e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos final SparseArray<Bitmap> bitmaps = params[0]; 17300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos List<UserInfo> infos = mUserManager.getUsers(true); 17400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (infos == null) { 17500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 17600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 17700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ArrayList<UserRecord> records = new ArrayList<>(infos.size()); 17800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int currentId = ActivityManager.getCurrentUser(); 1797cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserInfo currentUserInfo = null; 18000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord guestRecord = null; 1814d75c079f35d85b687d8349e5e2940447d01198eDan Sandler int avatarSize = mContext.getResources() 1824d75c079f35d85b687d8349e5e2940447d01198eDan Sandler .getDimensionPixelSize(R.dimen.max_avatar_size); 18300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 18400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (UserInfo info : infos) { 18500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean isCurrent = currentId == info.id; 1867cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (isCurrent) { 1877cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen currentUserInfo = info; 1887cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } 18900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info.isGuest()) { 19000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos guestRecord = new UserRecord(info, null /* picture */, 191ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, isCurrent, false /* isAddUser */, 192ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isRestricted */); 193cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } else if (info.isEnabled() && info.supportsSwitchToByUser()) { 194c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos Bitmap picture = bitmaps.get(info.id); 195c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos if (picture == null) { 196c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos picture = mUserManager.getUserIcon(info.id); 197cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos 198c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos if (picture != null) { 199cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos picture = BitmapHelper.createCircularClip( 200c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos picture, avatarSize, avatarSize); 201cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos } 2024d75c079f35d85b687d8349e5e2940447d01198eDan Sandler } 203bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = isCurrent ? 0 : records.size(); 204bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, new UserRecord(info, picture, false /* isGuest */, 205bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos isCurrent, false /* isAddUser */, false /* isRestricted */)); 20600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 20700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 20800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 2097cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean systemCanCreateUsers = !mUserManager.hasUserRestriction( 2107cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); 2117cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean currentUserCanCreateUsers = currentUserInfo != null 2127cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && (currentUserInfo.isAdmin() 2137cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen || currentUserInfo.id == UserHandle.USER_SYSTEM) 2147cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && systemCanCreateUsers; 2157cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked; 216ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) 217ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos && guestRecord == null; 218ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) 21995ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani && mUserManager.canAddMoreUsers(); 220ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean createIsRestricted = !addUsersWhenLocked; 221ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 2222daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (!mSimpleUserSwitcher) { 2232daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (guestRecord == null) { 224ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (canCreateGuest) { 225ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos records.add(new UserRecord(null /* info */, null /* picture */, 226ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, false /* isCurrent */, 227ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isAddUser */, createIsRestricted)); 228ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 2292daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } else { 230bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = guestRecord.isCurrent ? 0 : records.size(); 231bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, guestRecord); 2322daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 23300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 235092be7de024b8b1a050ad247a016febc795546afJason Monk if (!mSimpleUserSwitcher && canCreateUser) { 236ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos records.add(new UserRecord(null /* info */, null /* picture */, 237ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isGuest */, false /* isCurrent */, true /* isAddUser */, 238ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos createIsRestricted)); 239ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 240ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 24100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return records; 24200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 24300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 24400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 24500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected void onPostExecute(ArrayList<UserRecord> userRecords) { 24600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (userRecords != null) { 24700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers = userRecords; 24800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 24900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 25000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 251ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }.execute((SparseArray) bitmaps); 25200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 25300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 25488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private void pauseRefreshUsers() { 25588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (!mPauseRefreshUsers) { 25688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS); 25788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = true; 25888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 25988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 26088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 26100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private void notifyAdapters() { 26200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = mAdapters.size() - 1; i >= 0; i--) { 26300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos BaseUserAdapter adapter = mAdapters.get(i).get(); 26400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (adapter != null) { 26500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos adapter.notifyDataSetChanged(); 26600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 26700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mAdapters.remove(i); 26800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 26900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 2722daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public boolean isSimpleUserSwitcher() { 2732daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk return mSimpleUserSwitcher; 2742daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 2752daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 276cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public boolean useFullscreenUserSwitcher() { 277cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Use adb to override: 278cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off. 279cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on. 280cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Restart SystemUI or adb reboot. 281cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int DEFAULT = -1; 282cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int overrideUseFullscreenUserSwitcher = 283cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Settings.System.getInt(mContext.getContentResolver(), 284cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia "enable_fullscreen_user_switcher", DEFAULT); 285cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (overrideUseFullscreenUserSwitcher != DEFAULT) { 286cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return overrideUseFullscreenUserSwitcher != 0; 287cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 288cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Otherwise default to the build setting. 28940f9dabaa880eaff54099a3763224b241a6668e6Xiyuan Xia return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher); 290cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 291cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 292cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public void removeUserId(int userId) { 293cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (userId == UserHandle.USER_SYSTEM) { 294cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Log.w(TAG, "User " + userId + " could not removed."); 295cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return; 296cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 297cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (ActivityManager.getCurrentUser() == userId) { 298cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia switchToUserId(UserHandle.USER_SYSTEM); 299cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 300cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (mUserManager.removeUser(userId)) { 301cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia refreshUsers(UserHandle.USER_NULL); 302cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 303cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 304cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 30500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 30600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int id; 30700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isGuest && record.info == null) { 30800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos // No guest user. Create one. 309f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos UserInfo guest = mUserManager.createGuest( 310f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext, mContext.getString(R.string.guest_nickname)); 311f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (guest == null) { 312f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create guest, most likely because there already exists one, we just 313f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // haven't reloaded the user list yet. 314f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 315f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 316f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos id = guest.id; 317ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (record.isAddUser) { 3180c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos showAddUserDialog(); 3190c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos return; 32000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 32100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos id = record.info.id; 32200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 32300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 32400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (ActivityManager.getCurrentUser() == id) { 325e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.isGuest) { 3265005244f10442e75c1f48973fdddce5facf3f360Adrian Roos showExitGuestDialog(id); 327e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 32800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return; 32900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 33000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 331e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos switchToUserId(id); 332e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 333e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 334e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void switchToUserId(int id) { 33500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos try { 33688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos pauseRefreshUsers(); 33700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ActivityManagerNative.getDefault().switchUser(id); 33800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } catch (RemoteException e) { 33900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos Log.e(TAG, "Couldn't switch user.", e); 34000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 34100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 34200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 343860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private void stopUserId(int id) { 344860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen try { 3459cbfc9e212151e84910a22387365644916dde446Fyodor Kupolov ActivityManagerNative.getDefault().stopUser(id, /* force= */ false, null); 346860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } catch (RemoteException e) { 347860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen Log.e(TAG, "Couldn't stop user.", e); 348860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 349860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 350860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 3515005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private void showExitGuestDialog(int id) { 3525005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 3535005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 3545005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 3555005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = new ExitGuestDialog(mContext, id); 3565005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.show(); 3575005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 3585005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 3590c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private void showAddUserDialog() { 3600c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (mAddUserDialog != null && mAddUserDialog.isShowing()) { 3610c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.cancel(); 3620c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 3630c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog = new AddUserDialog(mContext); 3640c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.show(); 3650c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 3660c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 367e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void exitGuest(int id) { 3687cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen int newId = UserHandle.USER_SYSTEM; 3697cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (mLastNonGuestUser != UserHandle.USER_SYSTEM) { 37070441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser); 3717cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) { 37270441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos newId = info.id; 37370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 37470441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 37570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos switchToUserId(newId); 376e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos mUserManager.removeUser(id); 377e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 378e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 37900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private BroadcastReceiver mReceiver = new BroadcastReceiver() { 38000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 38100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void onReceive(Context context, Intent intent) { 3825005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (DEBUG) { 3835005244f10442e75c1f48973fdddce5facf3f360Adrian Roos Log.v(TAG, "Broadcast: a=" + intent.getAction() 3845005244f10442e75c1f48973fdddce5facf3f360Adrian Roos + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); 3855005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 38688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 38788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos boolean unpauseRefreshUsers = false; 38888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos int forcePictureLoadForId = UserHandle.USER_NULL; 38988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 390f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { 391f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov int currentUser = ActivityManager.getCurrentUser(); 392f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentUser); 393f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 394f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showExitGuestDialog(currentUser); 395f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 396f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov return; 39780996bbf40ff192117c391074ed2f9b2cde4e69aAdrian Roos } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) { 398860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen int currentUser = ActivityManager.getCurrentUser(); 399860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen if (currentUser != UserHandle.USER_SYSTEM) { 400860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen switchToUserId(UserHandle.USER_SYSTEM); 401860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen stopUserId(currentUser); 402860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 40388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 4045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4055005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4065005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = null; 4075005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 40900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4107cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen final UserInfo userInfo = mUserManager.getUserInfo(currentId); 41100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int N = mUsers.size(); 41200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < N; i++) { 41300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord record = mUsers.get(i); 414e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.info == null) continue; 41500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean shouldBeCurrent = record.info.id == currentId; 41600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isCurrent != shouldBeCurrent) { 41700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent)); 41800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 41970441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos if (shouldBeCurrent && !record.isGuest) { 42070441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos mLastNonGuestUser = record.info.id; 42170441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 4227cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) { 423ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Immediately remove restricted records in case the AsyncTask is too slow. 424ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mUsers.remove(i); 425ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos i--; 426ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 42700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 42800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 429860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 430860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest() 431860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen && userInfo.id != UserHandle.USER_SYSTEM) { 432860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen showLogoutNotification(currentId); 433860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 434ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 435ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov showGuestNotification(currentId); 436ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov } 43788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos unpauseRefreshUsers = true; 43888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { 439e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 440e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos UserHandle.USER_NULL); 441e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 442e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(forcePictureLoadForId); 44388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (unpauseRefreshUsers) { 44488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mUnpauseRefreshUsers.run(); 44588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 44600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 447f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 448f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private void showGuestNotification(int guestUserId) { 449f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov PendingIntent removeGuestPI = PendingIntent.getBroadcastAsUser(mContext, 4507cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM); 451f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov Notification notification = new Notification.Builder(mContext) 452f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setVisibility(Notification.VISIBILITY_SECRET) 453f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setPriority(Notification.PRIORITY_MIN) 454f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setSmallIcon(R.drawable.ic_person) 455f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setContentTitle(mContext.getString(R.string.guest_notification_title)) 456f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setContentText(mContext.getString(R.string.guest_notification_text)) 45752408f4fb5dab950847aa12e3bea44399ccd0d6eFyodor Kupolov .setContentIntent(removeGuestPI) 458f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setShowWhen(false) 459f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .addAction(R.drawable.ic_delete, 460f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov mContext.getString(R.string.guest_notification_remove_action), 461f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov removeGuestPI) 462f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .build(); 463d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, ID_REMOVE_GUEST, 464d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani notification, new UserHandle(guestUserId)); 465f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 466860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 467860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private void showLogoutNotification(int userId) { 468860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext, 469860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM); 470860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen Notification notification = new Notification.Builder(mContext) 471860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setVisibility(Notification.VISIBILITY_SECRET) 472860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setPriority(Notification.PRIORITY_MIN) 473860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setSmallIcon(R.drawable.ic_person) 474860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentTitle(mContext.getString(R.string.user_logout_notification_title)) 475860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentText(mContext.getString(R.string.user_logout_notification_text)) 47652408f4fb5dab950847aa12e3bea44399ccd0d6eFyodor Kupolov .setContentIntent(logoutPI) 477ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov .setOngoing(true) 478860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setShowWhen(false) 479860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .addAction(R.drawable.ic_delete, 480860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen mContext.getString(R.string.user_logout_notification_action), 481860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen logoutPI) 482860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .build(); 483860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER, ID_LOGOUT_USER, 484860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen notification, new UserHandle(userId)); 485860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 48600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 48700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 48888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Runnable mUnpauseRefreshUsers = new Runnable() { 48988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos @Override 49088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public void run() { 49188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.removeCallbacks(this); 49288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = false; 49388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos refreshUsers(UserHandle.USER_NULL); 49488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 49588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos }; 49688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 497ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 4982daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public void onChange(boolean selfChange) { 4992daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), 5002daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; 501ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), 502ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; 5032daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk refreshUsers(UserHandle.USER_NULL); 5042daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 5052daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 5062daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 50700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 50800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.println("UserSwitcherController state:"); 50970441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos pw.println(" mLastNonGuestUser=" + mLastNonGuestUser); 51000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" mUsers.size="); pw.println(mUsers.size()); 51100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < mUsers.size(); i++) { 51200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserRecord u = mUsers.get(i); 51300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" "); pw.println(u.toString()); 51400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 51500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 51600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 51757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos public String getCurrentUserName(Context context) { 51857cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (mUsers.isEmpty()) return null; 51957cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos UserRecord item = mUsers.get(0); 52057cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item == null || item.info == null) return null; 52157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item.isGuest) return context.getString(R.string.guest_nickname); 52257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos return item.info.name; 52357cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos } 52457cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos 52500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static abstract class BaseUserAdapter extends BaseAdapter { 52600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 52700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserSwitcherController mController; 52800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 52900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected BaseUserAdapter(UserSwitcherController controller) { 53000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController = controller; 53100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos controller.mAdapters.add(new WeakReference<>(this)); 53200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 53300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 53400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 53500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getCount() { 536ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing() 5378a3a964d0ad13374a4c4ee8a8a1b12aa00e577f0Jason Monk && mController.mKeyguardMonitor.isSecure() 538e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek && !mController.mKeyguardMonitor.canSkipBouncer(); 539ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (!secureKeyguardShowing) { 540ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return mController.mUsers.size(); 541ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 542ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // The lock screen is secure and showing. Filter out restricted records. 543ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final int N = mController.mUsers.size(); 544ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos int count = 0; 545ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos for (int i = 0; i < N; i++) { 546ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (mController.mUsers.get(i).isRestricted) { 547ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos break; 548ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else { 549ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos count++; 550ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 551ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 552ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return count; 55300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 55400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 55500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 55600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord getItem(int position) { 55700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return mController.mUsers.get(position); 55800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 55900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 56000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 56100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public long getItemId(int position) { 562e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return position; 56300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 56400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 56500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 56600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController.switchTo(record); 56700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 568e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 569e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos public String getName(Context context, UserRecord item) { 570e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isGuest) { 571e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isCurrent) { 572e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString(R.string.guest_exit_guest); 573e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 574e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString( 575e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); 576e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 577ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (item.isAddUser) { 578ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getString(R.string.user_add_user); 579e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 580e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return item.info.name; 581e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 582e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 583723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos 584ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public Drawable getDrawable(Context context, UserRecord item) { 585ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (item.isAddUser) { 586ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getDrawable(R.drawable.ic_add_circle_qs); 587ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 58864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina return UserIcons.getDefaultUserIcon(item.isGuest ? UserHandle.USER_NULL : item.info.id, 58964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina /* light= */ true); 590ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 591844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos 592844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos public void refresh() { 593844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos mController.refreshUsers(UserHandle.USER_NULL); 594844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos } 59500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 59600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 59700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static final class UserRecord { 59800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final UserInfo info; 59900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final Bitmap picture; 60000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isGuest; 60100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isCurrent; 602ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isAddUser; 603ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos /** If true, the record is only visible to the owner and only when unlocked. */ 604ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isRestricted; 60500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 606ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, 607ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean isAddUser, boolean isRestricted) { 60800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.info = info; 60900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.picture = picture; 61000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isGuest = isGuest; 61100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isCurrent = isCurrent; 612ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isAddUser = isAddUser; 613ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isRestricted = isRestricted; 61400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 61500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 61600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord copyWithIsCurrent(boolean _isCurrent) { 617ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted); 61800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 61900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 62000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public String toString() { 62100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos StringBuilder sb = new StringBuilder(); 62200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("UserRecord("); 62300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info != null) { 62400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("name=\"" + info.name + "\" id=" + info.id); 62500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 626ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) { 627ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add guest placeholder>"); 628ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (isAddUser) { 629ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add user placeholder>"); 630ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 63100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 632ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) sb.append(" <isGuest>"); 633ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isAddUser) sb.append(" <isAddUser>"); 634ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isCurrent) sb.append(" <isCurrent>"); 635ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (picture != null) sb.append(" <hasPicture>"); 636ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isRestricted) sb.append(" <isRestricted>"); 63700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append(')'); 63800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return sb.toString(); 63900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 64000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 64100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 64200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() { 64300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final Intent USER_SETTINGS_INTENT = new Intent("android.settings.USER_SETTINGS"); 64400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 64500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 646c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk public CharSequence getTitle() { 647c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk return mContext.getString(R.string.quick_settings_user_title); 64800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 64900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 65000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 65100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public View createDetailView(Context context, View convertView, ViewGroup parent) { 6521940892d891c1d2538f51608b6618af646ab7481Adrian Roos UserDetailView v; 65300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (!(convertView instanceof UserDetailView)) { 6541940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = UserDetailView.inflate(context, parent, false); 65500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos v.createAndSetAdapter(UserSwitcherController.this); 6561940892d891c1d2538f51608b6618af646ab7481Adrian Roos } else { 6571940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = (UserDetailView) convertView; 65800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 659844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos v.refreshAdapter(); 66000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return v; 66100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 66200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 66400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Intent getSettingsIntent() { 66500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return USER_SETTINGS_INTENT; 66600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 66700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 66900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Boolean getToggleState() { 67000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 67100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 67200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 67300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 67400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void setToggleState(boolean state) { 67500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 676457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 677457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 678457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 679457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren return MetricsLogger.QS_USERDETAIL; 680457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 68100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 6825005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 683ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { 684ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos @Override 685ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public void onKeyguardChanged() { 686ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos notifyAdapters(); 687ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 688ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }; 689ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 6905005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final class ExitGuestDialog extends SystemUIDialog implements 6915005244f10442e75c1f48973fdddce5facf3f360Adrian Roos DialogInterface.OnClickListener { 6925005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 6935005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final int mGuestId; 6945005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 6955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public ExitGuestDialog(Context context, int guestId) { 6965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos super(context); 6975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setTitle(R.string.guest_exit_guest_dialog_title); 6985005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); 6995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 700e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(android.R.string.cancel), this); 7015005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 702e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(R.string.guest_exit_guest_dialog_remove), this); 7035005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setCanceledOnTouchOutside(false); 7045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestId = guestId; 7055005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 7065005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 7075005244f10442e75c1f48973fdddce5facf3f360Adrian Roos @Override 7085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public void onClick(DialogInterface dialog, int which) { 7095005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (which == BUTTON_NEGATIVE) { 7105005244f10442e75c1f48973fdddce5facf3f360Adrian Roos cancel(); 7115005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } else { 7125005244f10442e75c1f48973fdddce5facf3f360Adrian Roos dismiss(); 7135005244f10442e75c1f48973fdddce5facf3f360Adrian Roos exitGuest(mGuestId); 7145005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 7155005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 7165005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 7170c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 7180c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private final class AddUserDialog extends SystemUIDialog implements 7190c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos DialogInterface.OnClickListener { 7200c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 7210c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public AddUserDialog(Context context) { 7220c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos super(context); 7230c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setTitle(R.string.user_add_user_title); 7240c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setMessage(context.getString(R.string.user_add_user_message_short)); 7250c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 7260c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.cancel), this); 7270c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 7280c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.ok), this); 7290c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 7300c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 7310c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos @Override 7320c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public void onClick(DialogInterface dialog, int which) { 7330c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (which == BUTTON_NEGATIVE) { 7340c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos cancel(); 7350c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } else { 7360c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos dismiss(); 737ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu if (ActivityManager.isUserAMonkey()) { 738ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu return; 739ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu } 740cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen UserInfo user = mUserManager.createUser( 741f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext.getString(R.string.user_new_user_name), 0 /* flags */); 742f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (user == null) { 743f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create user, most likely because there are too many, but we haven't 744f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // been able to reload the list yet. 745f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 746f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 747f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos int id = user.id; 74864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 74964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina id, /* light= */ false)); 75064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina mUserManager.setUserIcon(id, icon); 7510c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos switchToUserId(id); 7520c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 7530c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 7540c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 75500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos} 756