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; 352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.os.Handler; 3600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.RemoteException; 37e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.os.UserHandle; 3800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.UserManager; 392daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.provider.Settings; 40523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.PhoneStateListener; 41523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.TelephonyManager; 4200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log; 43e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray; 4488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseBooleanArray; 4500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View; 4600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup; 4700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter; 4800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 49f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent; 50117d5b4f28bbaf1b7458233ae5e101b9c41d7b64Chris Wrenimport com.android.internal.messages.SystemMessageProto.SystemMessage; 5164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 521c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils; 5364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver; 5464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R; 55e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roosimport com.android.systemui.SystemUI; 563c2c34bb039e92d68f466b7d194cbbe8241d8d60Winsonimport com.android.systemui.SystemUISecondaryUserService; 5764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.QSTile; 5864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView; 591c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.systemui.statusbar.phone.ActivityStarter; 6064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog; 6164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina 6200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor; 6300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter; 6400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference; 6500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList; 6600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List; 6700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 681c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 691c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 7000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/** 7100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Keeps a list of all users on the device for user switching. 7200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 7300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospublic class UserSwitcherController { 7400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 7500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private static final String TAG = "UserSwitcherController"; 765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private static final boolean DEBUG = false; 772daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = 782daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk "lockscreenSimpleUserSwitcher"; 79f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST"; 80860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String ACTION_LOGOUT_USER = "com.android.systemui.LOGOUT_USER"; 8188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000; 8200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 83d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String TAG_REMOVE_GUEST = "remove_guest"; 84860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String TAG_LOGOUT_USER = "logout_user"; 85860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 86d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; 87d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani 8800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final Context mContext; 8900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final UserManager mUserManager; 9000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); 915005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final GuestResumeSessionReceiver mGuestResumeSessionReceiver 925005244f10442e75c1f48973fdddce5facf3f360Adrian Roos = new GuestResumeSessionReceiver(); 93ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor mKeyguardMonitor; 9488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Handler mHandler; 951c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka private final ActivityStarter mActivityStarter; 9600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 9700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private ArrayList<UserRecord> mUsers = new ArrayList<>(); 985005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private Dialog mExitGuestDialog; 990c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private Dialog mAddUserDialog; 1007cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen private int mLastNonGuestUser = UserHandle.USER_SYSTEM; 101ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mSimpleUserSwitcher; 102ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mAddUsersWhenLocked; 10388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private boolean mPauseRefreshUsers; 1043c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private int mSecondaryUser = UserHandle.USER_NULL; 1053c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private Intent mSecondaryUserServiceIntent; 10688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); 10700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 10888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, 1091c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka Handler handler, ActivityStarter activityStarter) { 11000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mContext = context; 1115005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestResumeSessionReceiver.register(context); 112ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mKeyguardMonitor = keyguardMonitor; 11388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler = handler; 1141c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter = activityStarter; 11500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserManager = UserManager.get(context); 11600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos IntentFilter filter = new IntentFilter(); 11700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_ADDED); 11800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_REMOVED); 11900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 12000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 121ad2e4bf9f36cf612db6c397feca8effb125ee541Amith Yamasani filter.addAction(Intent.ACTION_USER_STOPPED); 12207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov filter.addAction(Intent.ACTION_USER_UNLOCKED); 1237cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 124e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos null /* permission */, null /* scheduler */); 1252daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 1263c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class); 1273c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 128d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter = new IntentFilter(); 129d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter.addAction(ACTION_REMOVE_GUEST); 130860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen filter.addAction(ACTION_LOGOUT_USER); 1315891a346abbde5bfe95a52633d05533406cc6a2eAmith Yamasani mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 132d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani PERMISSION_SELF, null /* scheduler */); 133ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1342daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mContext.getContentResolver().registerContentObserver( 1352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, 136ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 137ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mContext.getContentResolver().registerContentObserver( 138ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, 139ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 14007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov mContext.getContentResolver().registerContentObserver( 14107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.getUriFor( 14207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED), 14307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov true, mSettingsObserver); 144ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Fetch initial values. 145ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver.onChange(false); 146ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 147ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos keyguardMonitor.addCallback(mCallback); 148523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov listenForCallState(); 1492daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 150e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(UserHandle.USER_NULL); 15100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 15200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 153e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos /** 154e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * Refreshes users from UserManager. 155e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 156e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * The pictures are only loaded if they have not been loaded yet. 157e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 158e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * @param forcePictureLoadForId forces the picture of the given user to be reloaded. 159e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos */ 16095ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani @SuppressWarnings("unchecked") 161e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void refreshUsers(int forcePictureLoadForId) { 16288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")"); 16388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (forcePictureLoadForId != UserHandle.USER_NULL) { 16488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.put(forcePictureLoadForId, true); 16588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 16688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 16788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (mPauseRefreshUsers) { 16888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos return; 16988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 170c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos 171d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos boolean forceAllUsers = mForcePictureLoadForUserId.get(UserHandle.USER_ALL); 172c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); 173c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos final int N = mUsers.size(); 174c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos for (int i = 0; i < N; i++) { 175c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos UserRecord r = mUsers.get(i); 176d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos if (r == null || r.picture == null || r.info == null || forceAllUsers 177d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos || mForcePictureLoadForUserId.get(r.info.id)) { 178c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos continue; 179e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 180c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos bitmaps.put(r.info.id, r.picture); 181e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 18288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.clear(); 183e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 184ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final boolean addUsersWhenLocked = mAddUsersWhenLocked; 185e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { 186e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos @SuppressWarnings("unchecked") 18700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 188e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { 189e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos final SparseArray<Bitmap> bitmaps = params[0]; 19000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos List<UserInfo> infos = mUserManager.getUsers(true); 19100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (infos == null) { 19200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 19300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 19400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ArrayList<UserRecord> records = new ArrayList<>(infos.size()); 19500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int currentId = ActivityManager.getCurrentUser(); 196523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 1977cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserInfo currentUserInfo = null; 19800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord guestRecord = null; 19900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 20000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (UserInfo info : infos) { 20100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean isCurrent = currentId == info.id; 2027cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (isCurrent) { 2037cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen currentUserInfo = info; 2047cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } 205523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean switchToEnabled = canSwitchUsers || isCurrent; 2061ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isEnabled()) { 2071ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isGuest()) { 208523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Tapping guest icon triggers remove and a user switch therefore 209523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // the icon shouldn't be enabled even if the user is current 2101ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova guestRecord = new UserRecord(info, null /* picture */, 2111ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova true /* isGuest */, isCurrent, false /* isAddUser */, 212523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isRestricted */, canSwitchUsers); 2131ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } else if (info.supportsSwitchToByUser()) { 2141ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova Bitmap picture = bitmaps.get(info.id); 2151ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture == null) { 2161ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova picture = mUserManager.getUserIcon(info.id); 2171ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova 2181ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture != null) { 219aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky int avatarSize = mContext.getResources() 220aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky .getDimensionPixelSize(R.dimen.max_avatar_size); 221aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture = Bitmap.createScaledBitmap( 222aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture, avatarSize, avatarSize, true); 2231ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } 224cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos } 2251ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova int index = isCurrent ? 0 : records.size(); 2261ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova records.add(index, new UserRecord(info, picture, false /* isGuest */, 2271ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova isCurrent, false /* isAddUser */, false /* isRestricted */, 2281ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova switchToEnabled)); 2294d75c079f35d85b687d8349e5e2940447d01198eDan Sandler } 23000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 233a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction( 234a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); 2357cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean currentUserCanCreateUsers = currentUserInfo != null 2367cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && (currentUserInfo.isAdmin() 237a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka || currentUserInfo.id == UserHandle.USER_SYSTEM) 238a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka && systemCanCreateUsers; 239a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked; 240a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) 241ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos && guestRecord == null; 242a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) 24395ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani && mUserManager.canAddMoreUsers(); 244ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean createIsRestricted = !addUsersWhenLocked; 245ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 2462daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (!mSimpleUserSwitcher) { 2472daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (guestRecord == null) { 248ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (canCreateGuest) { 2491c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka guestRecord = new UserRecord(null /* info */, null /* picture */, 250ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, false /* isCurrent */, 251523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isAddUser */, createIsRestricted, canSwitchUsers); 252a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(guestRecord); 2531c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(guestRecord); 254ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 2552daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } else { 256bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = guestRecord.isCurrent ? 0 : records.size(); 257bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, guestRecord); 2582daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 25900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 26000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 261092be7de024b8b1a050ad247a016febc795546afJason Monk if (!mSimpleUserSwitcher && canCreateUser) { 2621c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */, 263ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isGuest */, false /* isCurrent */, true /* isAddUser */, 264523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov createIsRestricted, canSwitchUsers); 265a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(addUserRecord); 2661c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(addUserRecord); 267ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 268ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 26900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return records; 27000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 27200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 27300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected void onPostExecute(ArrayList<UserRecord> userRecords) { 27400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (userRecords != null) { 27500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers = userRecords; 27600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 27700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 279ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }.execute((SparseArray) bitmaps); 28000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 28100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 28288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private void pauseRefreshUsers() { 28388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (!mPauseRefreshUsers) { 28488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS); 28588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = true; 28688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 28788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 28888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 28900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private void notifyAdapters() { 29000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = mAdapters.size() - 1; i >= 0; i--) { 29100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos BaseUserAdapter adapter = mAdapters.get(i).get(); 29200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (adapter != null) { 29300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos adapter.notifyDataSetChanged(); 29400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 29500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mAdapters.remove(i); 29600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 29700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 29800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 29900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 3002daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public boolean isSimpleUserSwitcher() { 3012daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk return mSimpleUserSwitcher; 3022daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 3032daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 304cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public boolean useFullscreenUserSwitcher() { 305cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Use adb to override: 306cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off. 307cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on. 308cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Restart SystemUI or adb reboot. 309cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int DEFAULT = -1; 310cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int overrideUseFullscreenUserSwitcher = 311cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Settings.System.getInt(mContext.getContentResolver(), 312cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia "enable_fullscreen_user_switcher", DEFAULT); 313cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (overrideUseFullscreenUserSwitcher != DEFAULT) { 314cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return overrideUseFullscreenUserSwitcher != 0; 315cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 316cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Otherwise default to the build setting. 31740f9dabaa880eaff54099a3763224b241a6668e6Xiyuan Xia return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher); 318cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 319cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 3201b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia public void logoutCurrentUser() { 3211b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia int currentUser = ActivityManager.getCurrentUser(); 3221b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia if (currentUser != UserHandle.USER_SYSTEM) { 323b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov pauseRefreshUsers(); 324b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov ActivityManager.logoutCurrentUser(); 3251b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3261b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3271b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia 328cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public void removeUserId(int userId) { 329cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (userId == UserHandle.USER_SYSTEM) { 330cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Log.w(TAG, "User " + userId + " could not removed."); 331cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return; 332cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 333cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (ActivityManager.getCurrentUser() == userId) { 334cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia switchToUserId(UserHandle.USER_SYSTEM); 335cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 336cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (mUserManager.removeUser(userId)) { 337cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia refreshUsers(UserHandle.USER_NULL); 338cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 339cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 340cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 34100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 34200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int id; 34300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isGuest && record.info == null) { 34400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos // No guest user. Create one. 345f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos UserInfo guest = mUserManager.createGuest( 346f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext, mContext.getString(R.string.guest_nickname)); 347f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (guest == null) { 348f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create guest, most likely because there already exists one, we just 349f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // haven't reloaded the user list yet. 350f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 351f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 352f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos id = guest.id; 353ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (record.isAddUser) { 3540c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos showAddUserDialog(); 3550c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos return; 35600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 35700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos id = record.info.id; 35800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 35900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 36000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (ActivityManager.getCurrentUser() == id) { 361e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.isGuest) { 3625005244f10442e75c1f48973fdddce5facf3f360Adrian Roos showExitGuestDialog(id); 363e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 36400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return; 36500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 36600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 367e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos switchToUserId(id); 368e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 369e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 370caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov public void switchTo(int userId) { 371caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov final int count = mUsers.size(); 372caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov for (int i = 0; i < count; ++i) { 373caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov UserRecord record = mUsers.get(i); 374caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov if (record.info != null && record.info.id == userId) { 375caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov switchTo(record); 376caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov return; 377caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 378caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 379caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 380caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov Log.e(TAG, "Couldn't switch to user, id=" + userId); 381caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 382caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 3838ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi public int getSwitchableUserCount() { 3848ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi int count = 0; 3858ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi final int N = mUsers.size(); 3868ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi for (int i = 0; i < N; ++i) { 3878ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi UserRecord record = mUsers.get(i); 3888ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi if (record.info != null && record.info.supportsSwitchTo()) { 3898ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi count++; 3908ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 3918ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 3928ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi return count; 3938ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 3948ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi 395e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void switchToUserId(int id) { 39600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos try { 39788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos pauseRefreshUsers(); 39800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ActivityManagerNative.getDefault().switchUser(id); 39900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } catch (RemoteException e) { 40000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos Log.e(TAG, "Couldn't switch user.", e); 40100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 40200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 40300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 4045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private void showExitGuestDialog(int id) { 4055005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4065005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4075005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = new ExitGuestDialog(mContext, id); 4095005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.show(); 4105005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4115005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 4120c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private void showAddUserDialog() { 4130c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (mAddUserDialog != null && mAddUserDialog.isShowing()) { 4140c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.cancel(); 4150c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4160c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog = new AddUserDialog(mContext); 4170c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.show(); 4180c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4190c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 420e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void exitGuest(int id) { 4217cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen int newId = UserHandle.USER_SYSTEM; 4227cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (mLastNonGuestUser != UserHandle.USER_SYSTEM) { 42370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser); 4247cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) { 42570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos newId = info.id; 42670441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 42770441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 42870441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos switchToUserId(newId); 429e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos mUserManager.removeUser(id); 430e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 431e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 432523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void listenForCallState() { 433705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk TelephonyManager.from(mContext).listen(mPhoneStateListener, 434705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk PhoneStateListener.LISTEN_CALL_STATE); 435523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 436523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 437705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 438705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private int mCallState; 439705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 440705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk @Override 441705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk public void onCallStateChanged(int state, String incomingNumber) { 442705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (mCallState == state) return; 443705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (DEBUG) Log.v(TAG, "Call state changed: " + state); 444705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk mCallState = state; 445705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk int currentUserId = ActivityManager.getCurrentUser(); 446705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk UserInfo userInfo = mUserManager.getUserInfo(currentUserId); 447705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (userInfo != null && userInfo.isGuest()) { 448705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk showGuestNotification(currentUserId); 449705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 450705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk refreshUsers(UserHandle.USER_NULL); 451705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 452705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk }; 453705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 45400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private BroadcastReceiver mReceiver = new BroadcastReceiver() { 45500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 45600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void onReceive(Context context, Intent intent) { 4575005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (DEBUG) { 4585005244f10442e75c1f48973fdddce5facf3f360Adrian Roos Log.v(TAG, "Broadcast: a=" + intent.getAction() 4595005244f10442e75c1f48973fdddce5facf3f360Adrian Roos + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); 4605005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 46188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 46288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos boolean unpauseRefreshUsers = false; 46388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos int forcePictureLoadForId = UserHandle.USER_NULL; 46488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 465f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { 466f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov int currentUser = ActivityManager.getCurrentUser(); 467f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentUser); 468f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 469f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showExitGuestDialog(currentUser); 470f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 471f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov return; 47280996bbf40ff192117c391074ed2f9b2cde4e69aAdrian Roos } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) { 4731b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia logoutCurrentUser(); 47488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 4755005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4775005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = null; 4785005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 48000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4817cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen final UserInfo userInfo = mUserManager.getUserInfo(currentId); 48200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int N = mUsers.size(); 48300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < N; i++) { 48400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord record = mUsers.get(i); 485e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.info == null) continue; 48600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean shouldBeCurrent = record.info.id == currentId; 48700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isCurrent != shouldBeCurrent) { 48800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent)); 48900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 49070441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos if (shouldBeCurrent && !record.isGuest) { 49170441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos mLastNonGuestUser = record.info.id; 49270441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 4937cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) { 494ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Immediately remove restricted records in case the AsyncTask is too slow. 495ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mUsers.remove(i); 496ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos i--; 497ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 49800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 49900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 500860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 5013c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Disconnect from the old secondary user's service 5023c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson if (mSecondaryUser != UserHandle.USER_NULL) { 5033c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.stopServiceAsUser(mSecondaryUserServiceIntent, 5043c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(mSecondaryUser)); 5053c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = UserHandle.USER_NULL; 5063c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5073c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Connect to the new secondary user's service (purely to ensure that a persistent 5083c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // SystemUI application is created for that user) 5093c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson if (userInfo != null && !userInfo.isPrimary()) { 5103c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.startServiceAsUser(mSecondaryUserServiceIntent, 5113c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(userInfo.id)); 5123c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = userInfo.id; 5133c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5143c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 515860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest() 516860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen && userInfo.id != UserHandle.USER_SYSTEM) { 517860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen showLogoutNotification(currentId); 518860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 519ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 520ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov showGuestNotification(currentId); 521ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov } 52288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos unpauseRefreshUsers = true; 52388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { 524e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 525e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos UserHandle.USER_NULL); 52607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { 52707140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov // Unlocking the system user may require a refresh 52807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 52907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (userId != UserHandle.USER_SYSTEM) { 53007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return; 53107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 532e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 533e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(forcePictureLoadForId); 53488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (unpauseRefreshUsers) { 53588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mUnpauseRefreshUsers.run(); 53688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 53700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 538f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 539860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private void showLogoutNotification(int userId) { 540860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext, 541860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM); 542e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos Notification.Builder builder = new Notification.Builder(mContext) 543860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setVisibility(Notification.VISIBILITY_SECRET) 544860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setPriority(Notification.PRIORITY_MIN) 545860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setSmallIcon(R.drawable.ic_person) 546860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentTitle(mContext.getString(R.string.user_logout_notification_title)) 547860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentText(mContext.getString(R.string.user_logout_notification_text)) 54852408f4fb5dab950847aa12e3bea44399ccd0d6eFyodor Kupolov .setContentIntent(logoutPI) 549ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov .setOngoing(true) 550860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setShowWhen(false) 551860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .addAction(R.drawable.ic_delete, 552860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen mContext.getString(R.string.user_logout_notification_action), 553e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos logoutPI); 554e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 555117d5b4f28bbaf1b7458233ae5e101b9c41d7b64Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER, 556117d5b4f28bbaf1b7458233ae5e101b9c41d7b64Chris Wren SystemMessage.NOTE_LOGOUT_USER, builder.build(), new UserHandle(userId)); 557860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 55800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 55900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 560523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void showGuestNotification(int guestUserId) { 561523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 562523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Disable 'Remove guest' action if cannot switch users right now 563523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext, 564523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null; 565523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 566e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos Notification.Builder builder = new Notification.Builder(mContext) 567523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setVisibility(Notification.VISIBILITY_SECRET) 568523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setPriority(Notification.PRIORITY_MIN) 569523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setSmallIcon(R.drawable.ic_person) 570523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentTitle(mContext.getString(R.string.guest_notification_title)) 571523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentText(mContext.getString(R.string.guest_notification_text)) 572523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentIntent(removeGuestPI) 573523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setShowWhen(false) 574523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .addAction(R.drawable.ic_delete, 575523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov mContext.getString(R.string.guest_notification_remove_action), 576e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos removeGuestPI); 577e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 578117d5b4f28bbaf1b7458233ae5e101b9c41d7b64Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, 579117d5b4f28bbaf1b7458233ae5e101b9c41d7b64Chris Wren SystemMessage.NOTE_REMOVE_GUEST, builder.build(), new UserHandle(guestUserId)); 580523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 581523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 58288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Runnable mUnpauseRefreshUsers = new Runnable() { 58388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos @Override 58488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public void run() { 58588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.removeCallbacks(this); 58688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = false; 58788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos refreshUsers(UserHandle.USER_NULL); 58888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 58988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos }; 59088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 591ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 5922daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public void onChange(boolean selfChange) { 5932daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), 5942daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; 595ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), 596ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; 5972daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk refreshUsers(UserHandle.USER_NULL); 5982daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 5992daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 6002daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 60100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 60200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.println("UserSwitcherController state:"); 60370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos pw.println(" mLastNonGuestUser=" + mLastNonGuestUser); 60400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" mUsers.size="); pw.println(mUsers.size()); 60500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < mUsers.size(); i++) { 60600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserRecord u = mUsers.get(i); 60700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" "); pw.println(u.toString()); 60800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 60900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 61000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 61157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos public String getCurrentUserName(Context context) { 61257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (mUsers.isEmpty()) return null; 61357cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos UserRecord item = mUsers.get(0); 61457cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item == null || item.info == null) return null; 61557cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item.isGuest) return context.getString(R.string.guest_nickname); 61657cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos return item.info.name; 61757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos } 61857cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos 619d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos public void onDensityOrFontScaleChanged() { 620d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos refreshUsers(UserHandle.USER_ALL); 621d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos } 622d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos 62300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static abstract class BaseUserAdapter extends BaseAdapter { 62400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 62500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserSwitcherController mController; 62600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 62700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected BaseUserAdapter(UserSwitcherController controller) { 62800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController = controller; 62900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos controller.mAdapters.add(new WeakReference<>(this)); 63000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 63100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 63200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 63300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getCount() { 634ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing() 6358a3a964d0ad13374a4c4ee8a8a1b12aa00e577f0Jason Monk && mController.mKeyguardMonitor.isSecure() 636e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek && !mController.mKeyguardMonitor.canSkipBouncer(); 637ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (!secureKeyguardShowing) { 638ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return mController.mUsers.size(); 639ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 640ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // The lock screen is secure and showing. Filter out restricted records. 641ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final int N = mController.mUsers.size(); 642ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos int count = 0; 643ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos for (int i = 0; i < N; i++) { 644ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (mController.mUsers.get(i).isRestricted) { 645ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos break; 646ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else { 647ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos count++; 648ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 649ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 650ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return count; 65100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 65200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 65300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 65400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord getItem(int position) { 65500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return mController.mUsers.get(position); 65600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 65700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 65800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 65900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public long getItemId(int position) { 660e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return position; 66100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 66200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 66400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController.switchTo(record); 66500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 666e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 667e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos public String getName(Context context, UserRecord item) { 668e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isGuest) { 669e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isCurrent) { 670e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString(R.string.guest_exit_guest); 671e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 672e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString( 673e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); 674e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 675ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (item.isAddUser) { 676ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getString(R.string.user_add_user); 677e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 678e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return item.info.name; 679e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 680e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 681723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos 682ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public Drawable getDrawable(Context context, UserRecord item) { 683ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (item.isAddUser) { 684ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getDrawable(R.drawable.ic_add_circle_qs); 685ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 686aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return UserIcons.getDefaultUserIcon(item.resolveId(), /* light= */ true); 687ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 688844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos 689844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos public void refresh() { 690844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos mController.refreshUsers(UserHandle.USER_NULL); 691844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos } 69200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 69300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 694a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) { 695ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext, 696ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser()); 697ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext, 698ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) { 6991c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = true; 700ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka record.enforcedAdmin = admin; 7011c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } else { 7021c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = false; 7031c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.enforcedAdmin = null; 7041c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7051c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7061c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 7071c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public void startActivity(Intent intent) { 7081c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter.startActivity(intent, true); 7091c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7101c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 71100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static final class UserRecord { 71200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final UserInfo info; 71300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final Bitmap picture; 71400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isGuest; 71500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isCurrent; 716ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isAddUser; 717ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos /** If true, the record is only visible to the owner and only when unlocked. */ 718ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isRestricted; 7191c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public boolean isDisabledByAdmin; 7201c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public EnforcedAdmin enforcedAdmin; 72107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov public boolean isSwitchToEnabled; 72200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 723ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, 72407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov boolean isAddUser, boolean isRestricted, boolean isSwitchToEnabled) { 72500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.info = info; 72600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.picture = picture; 72700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isGuest = isGuest; 72800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isCurrent = isCurrent; 729ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isAddUser = isAddUser; 730ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isRestricted = isRestricted; 73107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov this.isSwitchToEnabled = isSwitchToEnabled; 73200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 73300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 73400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord copyWithIsCurrent(boolean _isCurrent) { 73507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted, 73607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov isSwitchToEnabled); 73700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 73800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 739aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky public int resolveId() { 740aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky if (isGuest || info == null) { 741aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return UserHandle.USER_NULL; 742aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 743aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return info.id; 744aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 745aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky 74600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public String toString() { 74700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos StringBuilder sb = new StringBuilder(); 74800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("UserRecord("); 74900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info != null) { 75007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append("name=\"").append(info.name).append("\" id=").append(info.id); 75100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 752ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) { 753ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add guest placeholder>"); 754ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (isAddUser) { 755ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add user placeholder>"); 756ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 75700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 758ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) sb.append(" <isGuest>"); 759ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isAddUser) sb.append(" <isAddUser>"); 760ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isCurrent) sb.append(" <isCurrent>"); 761ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (picture != null) sb.append(" <hasPicture>"); 762ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isRestricted) sb.append(" <isRestricted>"); 7631c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka if (isDisabledByAdmin) { 7641c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka sb.append(" <isDisabledByAdmin>"); 76507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" enforcedAdmin=").append(enforcedAdmin); 76607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 76707140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (isSwitchToEnabled) { 76807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" <isSwitchToEnabled>"); 7691c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 77000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append(')'); 77100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return sb.toString(); 77200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 77300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 77400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 77500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() { 77676c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS); 77700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 77800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 779c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk public CharSequence getTitle() { 780c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk return mContext.getString(R.string.quick_settings_user_title); 78100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 78200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 78300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 78400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public View createDetailView(Context context, View convertView, ViewGroup parent) { 7851940892d891c1d2538f51608b6618af646ab7481Adrian Roos UserDetailView v; 78600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (!(convertView instanceof UserDetailView)) { 7871940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = UserDetailView.inflate(context, parent, false); 78800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos v.createAndSetAdapter(UserSwitcherController.this); 7891940892d891c1d2538f51608b6618af646ab7481Adrian Roos } else { 7901940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = (UserDetailView) convertView; 79100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 792844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos v.refreshAdapter(); 79300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return v; 79400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 79500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 79600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 79700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Intent getSettingsIntent() { 79800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return USER_SETTINGS_INTENT; 79900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 80000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 80100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 80200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Boolean getToggleState() { 80300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 80400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 80500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 80600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 80700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void setToggleState(boolean state) { 80800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 809457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 810457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 811457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 812f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren return MetricsEvent.QS_USERDETAIL; 813457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 81400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 8155005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 816ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { 817ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos @Override 818ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public void onKeyguardChanged() { 819ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos notifyAdapters(); 820ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 821ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }; 822ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 8235005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final class ExitGuestDialog extends SystemUIDialog implements 8245005244f10442e75c1f48973fdddce5facf3f360Adrian Roos DialogInterface.OnClickListener { 8255005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8265005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final int mGuestId; 8275005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8285005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public ExitGuestDialog(Context context, int guestId) { 8295005244f10442e75c1f48973fdddce5facf3f360Adrian Roos super(context); 8305005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setTitle(R.string.guest_exit_guest_dialog_title); 8315005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); 8325005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 833e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(android.R.string.cancel), this); 8345005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 835e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(R.string.guest_exit_guest_dialog_remove), this); 8365005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setCanceledOnTouchOutside(false); 8375005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestId = guestId; 8385005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8395005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8405005244f10442e75c1f48973fdddce5facf3f360Adrian Roos @Override 8415005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public void onClick(DialogInterface dialog, int which) { 8425005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (which == BUTTON_NEGATIVE) { 8435005244f10442e75c1f48973fdddce5facf3f360Adrian Roos cancel(); 8445005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } else { 8455005244f10442e75c1f48973fdddce5facf3f360Adrian Roos dismiss(); 8465005244f10442e75c1f48973fdddce5facf3f360Adrian Roos exitGuest(mGuestId); 8475005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8485005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8495005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8500c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 8510c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private final class AddUserDialog extends SystemUIDialog implements 8520c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos DialogInterface.OnClickListener { 8530c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 8540c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public AddUserDialog(Context context) { 8550c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos super(context); 8560c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setTitle(R.string.user_add_user_title); 8570c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setMessage(context.getString(R.string.user_add_user_message_short)); 8580c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 8590c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.cancel), this); 8600c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 8610c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.ok), this); 8620c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 8630c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 8640c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos @Override 8650c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public void onClick(DialogInterface dialog, int which) { 8660c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (which == BUTTON_NEGATIVE) { 8670c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos cancel(); 8680c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } else { 8690c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos dismiss(); 870ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu if (ActivityManager.isUserAMonkey()) { 871ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu return; 872ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu } 873cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen UserInfo user = mUserManager.createUser( 874f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext.getString(R.string.user_new_user_name), 0 /* flags */); 875f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (user == null) { 876f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create user, most likely because there are too many, but we haven't 877f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // been able to reload the list yet. 878f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 879f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 880f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos int id = user.id; 88164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 88264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina id, /* light= */ false)); 88364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina mUserManager.setUserIcon(id, icon); 8840c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos switchToUserId(id); 8850c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 8860c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 8870c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 88800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos} 889