UserSwitcherController.java revision 5e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4
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 19ec015d5cb510d26d4e951feb240be8025f477ff5Xiaohui Chenimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 20ec015d5cb510d26d4e951feb240be8025f477ff5Xiaohui Chen 2100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManager; 225005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.app.Dialog; 23f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.Notification; 24f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.NotificationManager; 25f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.PendingIntent; 2600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.BroadcastReceiver; 2700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Context; 285005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.content.DialogInterface; 2900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Intent; 3000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.IntentFilter; 3100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.pm.UserInfo; 322daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.database.ContentObserver; 3300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.graphics.Bitmap; 34ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roosimport android.graphics.drawable.Drawable; 3500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.AsyncTask; 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; 41523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.PhoneStateListener; 42523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.TelephonyManager; 4300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log; 44e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray; 4588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseBooleanArray; 4600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View; 4700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup; 4800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter; 4900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 50383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 518852905b0b3837e326127c6dfef6f699124ce715Jason Monkimport com.android.internal.annotations.VisibleForTesting; 525e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wrenimport com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 5364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 541c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils; 5564d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver; 5664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R; 57e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roosimport com.android.systemui.SystemUI; 583c2c34bb039e92d68f466b7d194cbbe8241d8d60Winsonimport com.android.systemui.SystemUISecondaryUserService; 590ceef211875515c2a7531f9baeae46339e700f3aJason Monkimport com.android.systemui.plugins.qs.QS.DetailAdapter; 6064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView; 610ceef211875515c2a7531f9baeae46339e700f3aJason Monkimport com.android.systemui.plugins.qs.QS.ActivityStarter; 6264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog; 6364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina 6400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor; 6500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter; 6600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference; 6700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList; 6800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List; 6900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 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 8813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected final Context mContext; 8913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected 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; 9413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected 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; 10137c76807a047193338e3af317fb39373d69c7561Evan Rosky private boolean mResumeUserOnGuestLogout = true; 102ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mSimpleUserSwitcher; 103ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mAddUsersWhenLocked; 10488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private boolean mPauseRefreshUsers; 1053c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private int mSecondaryUser = UserHandle.USER_NULL; 1063c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private Intent mSecondaryUserServiceIntent; 10788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); 10800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 10988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, 1101c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka Handler handler, ActivityStarter activityStarter) { 11100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mContext = context; 1125005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestResumeSessionReceiver.register(context); 113ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mKeyguardMonitor = keyguardMonitor; 11488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler = handler; 1151c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter = activityStarter; 11600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserManager = UserManager.get(context); 11700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos IntentFilter filter = new IntentFilter(); 11800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_ADDED); 11900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_REMOVED); 12000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 12100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 122ad2e4bf9f36cf612db6c397feca8effb125ee541Amith Yamasani filter.addAction(Intent.ACTION_USER_STOPPED); 12307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov filter.addAction(Intent.ACTION_USER_UNLOCKED); 1247cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 125e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos null /* permission */, null /* scheduler */); 1262daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 1273c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class); 1283c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 129d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter = new IntentFilter(); 130d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter.addAction(ACTION_REMOVE_GUEST); 131860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen filter.addAction(ACTION_LOGOUT_USER); 1325891a346abbde5bfe95a52633d05533406cc6a2eAmith Yamasani mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 133d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani PERMISSION_SELF, null /* scheduler */); 134ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mContext.getContentResolver().registerContentObserver( 1362daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, 137ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 138ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mContext.getContentResolver().registerContentObserver( 139ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, 140ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 14107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov mContext.getContentResolver().registerContentObserver( 14207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.getUriFor( 14307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED), 14407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov true, mSettingsObserver); 145ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Fetch initial values. 146ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver.onChange(false); 147ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 148ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos keyguardMonitor.addCallback(mCallback); 149523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov listenForCallState(); 1502daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 151e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(UserHandle.USER_NULL); 15200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 15300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 154e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos /** 155e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * Refreshes users from UserManager. 156e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 157e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * The pictures are only loaded if they have not been loaded yet. 158e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 159e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * @param forcePictureLoadForId forces the picture of the given user to be reloaded. 160e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos */ 16195ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani @SuppressWarnings("unchecked") 162e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void refreshUsers(int forcePictureLoadForId) { 16388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")"); 16488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (forcePictureLoadForId != UserHandle.USER_NULL) { 16588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.put(forcePictureLoadForId, true); 16688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 16788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 16888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (mPauseRefreshUsers) { 16988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos return; 17088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 171c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos 172d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos boolean forceAllUsers = mForcePictureLoadForUserId.get(UserHandle.USER_ALL); 173c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); 174c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos final int N = mUsers.size(); 175c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos for (int i = 0; i < N; i++) { 176c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos UserRecord r = mUsers.get(i); 177d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos if (r == null || r.picture == null || r.info == null || forceAllUsers 178d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos || mForcePictureLoadForUserId.get(r.info.id)) { 179c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos continue; 180e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 181c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos bitmaps.put(r.info.id, r.picture); 182e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 18388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.clear(); 184e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 185ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final boolean addUsersWhenLocked = mAddUsersWhenLocked; 186e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { 187e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos @SuppressWarnings("unchecked") 18800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 189e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { 190e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos final SparseArray<Bitmap> bitmaps = params[0]; 19100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos List<UserInfo> infos = mUserManager.getUsers(true); 19200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (infos == null) { 19300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 19400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 19500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ArrayList<UserRecord> records = new ArrayList<>(infos.size()); 19600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int currentId = ActivityManager.getCurrentUser(); 197523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 1987cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserInfo currentUserInfo = null; 19900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord guestRecord = null; 20000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 20100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (UserInfo info : infos) { 20200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean isCurrent = currentId == info.id; 2037cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (isCurrent) { 2047cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen currentUserInfo = info; 2057cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } 206523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean switchToEnabled = canSwitchUsers || isCurrent; 2071ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isEnabled()) { 2081ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isGuest()) { 209523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Tapping guest icon triggers remove and a user switch therefore 210523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // the icon shouldn't be enabled even if the user is current 2111ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova guestRecord = new UserRecord(info, null /* picture */, 2121ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova true /* isGuest */, isCurrent, false /* isAddUser */, 213523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isRestricted */, canSwitchUsers); 2141ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } else if (info.supportsSwitchToByUser()) { 2151ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova Bitmap picture = bitmaps.get(info.id); 2161ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture == null) { 2171ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova picture = mUserManager.getUserIcon(info.id); 2181ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova 2191ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture != null) { 220aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky int avatarSize = mContext.getResources() 221aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky .getDimensionPixelSize(R.dimen.max_avatar_size); 222aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture = Bitmap.createScaledBitmap( 223aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture, avatarSize, avatarSize, true); 2241ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } 225cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos } 2261ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova int index = isCurrent ? 0 : records.size(); 2271ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova records.add(index, new UserRecord(info, picture, false /* isGuest */, 2281ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova isCurrent, false /* isAddUser */, false /* isRestricted */, 2291ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova switchToEnabled)); 2304d75c079f35d85b687d8349e5e2940447d01198eDan Sandler } 23100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 234a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction( 235a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); 2367cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean currentUserCanCreateUsers = currentUserInfo != null 2377cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && (currentUserInfo.isAdmin() 238a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka || currentUserInfo.id == UserHandle.USER_SYSTEM) 239a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka && systemCanCreateUsers; 240a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked; 241a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) 242ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos && guestRecord == null; 243a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) 24495ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani && mUserManager.canAddMoreUsers(); 245ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean createIsRestricted = !addUsersWhenLocked; 246ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 2472daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (!mSimpleUserSwitcher) { 2482daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (guestRecord == null) { 249ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (canCreateGuest) { 2501c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka guestRecord = new UserRecord(null /* info */, null /* picture */, 251ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, false /* isCurrent */, 252523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isAddUser */, createIsRestricted, canSwitchUsers); 253a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(guestRecord); 2541c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(guestRecord); 255ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 2562daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } else { 257bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = guestRecord.isCurrent ? 0 : records.size(); 258bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, guestRecord); 2592daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 26000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 26100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 262092be7de024b8b1a050ad247a016febc795546afJason Monk if (!mSimpleUserSwitcher && canCreateUser) { 2631c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */, 264ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isGuest */, false /* isCurrent */, true /* isAddUser */, 265523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov createIsRestricted, canSwitchUsers); 266a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(addUserRecord); 2671c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(addUserRecord); 268ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 269ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 27000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return records; 27100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 27300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 27400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected void onPostExecute(ArrayList<UserRecord> userRecords) { 27500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (userRecords != null) { 27600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers = userRecords; 27700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 27800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 280ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }.execute((SparseArray) bitmaps); 28100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 28200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 28388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private void pauseRefreshUsers() { 28488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (!mPauseRefreshUsers) { 28588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS); 28688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = true; 28788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 28888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 28988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 29000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private void notifyAdapters() { 29100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = mAdapters.size() - 1; i >= 0; i--) { 29200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos BaseUserAdapter adapter = mAdapters.get(i).get(); 29300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (adapter != null) { 29400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos adapter.notifyDataSetChanged(); 29500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 29600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mAdapters.remove(i); 29700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 29800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 29900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 30000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 3012daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public boolean isSimpleUserSwitcher() { 3022daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk return mSimpleUserSwitcher; 3032daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 3042daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 305cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public boolean useFullscreenUserSwitcher() { 306cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Use adb to override: 307cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off. 308cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on. 309cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Restart SystemUI or adb reboot. 310cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int DEFAULT = -1; 311cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int overrideUseFullscreenUserSwitcher = 312cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Settings.System.getInt(mContext.getContentResolver(), 313cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia "enable_fullscreen_user_switcher", DEFAULT); 314cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (overrideUseFullscreenUserSwitcher != DEFAULT) { 315cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return overrideUseFullscreenUserSwitcher != 0; 316cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 317cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Otherwise default to the build setting. 31840f9dabaa880eaff54099a3763224b241a6668e6Xiyuan Xia return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher); 319cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 320cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 32137c76807a047193338e3af317fb39373d69c7561Evan Rosky public void setResumeUserOnGuestLogout(boolean resume) { 32237c76807a047193338e3af317fb39373d69c7561Evan Rosky mResumeUserOnGuestLogout = resume; 32337c76807a047193338e3af317fb39373d69c7561Evan Rosky } 32437c76807a047193338e3af317fb39373d69c7561Evan Rosky 3251b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia public void logoutCurrentUser() { 3261b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia int currentUser = ActivityManager.getCurrentUser(); 3271b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia if (currentUser != UserHandle.USER_SYSTEM) { 328b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov pauseRefreshUsers(); 329b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov ActivityManager.logoutCurrentUser(); 3301b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3311b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3321b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia 333cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public void removeUserId(int userId) { 334cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (userId == UserHandle.USER_SYSTEM) { 335cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Log.w(TAG, "User " + userId + " could not removed."); 336cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return; 337cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 338cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (ActivityManager.getCurrentUser() == userId) { 339cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia switchToUserId(UserHandle.USER_SYSTEM); 340cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 341cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (mUserManager.removeUser(userId)) { 342cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia refreshUsers(UserHandle.USER_NULL); 343cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 344cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 345cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 34600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 34700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int id; 34800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isGuest && record.info == null) { 34900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos // No guest user. Create one. 350f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos UserInfo guest = mUserManager.createGuest( 351f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext, mContext.getString(R.string.guest_nickname)); 352f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (guest == null) { 353f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create guest, most likely because there already exists one, we just 354f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // haven't reloaded the user list yet. 355f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 356f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 357f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos id = guest.id; 358ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (record.isAddUser) { 3590c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos showAddUserDialog(); 3600c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos return; 36100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 36200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos id = record.info.id; 36300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 36400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 36513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky int currUserId = ActivityManager.getCurrentUser(); 36613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (currUserId == id) { 367e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.isGuest) { 3685005244f10442e75c1f48973fdddce5facf3f360Adrian Roos showExitGuestDialog(id); 369e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 37000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return; 37100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 37200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 37313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (UserManager.isGuestUserEphemeral()) { 37413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky // If switching from guest, we want to bring up the guest exit dialog instead of switching 37513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky UserInfo currUserInfo = mUserManager.getUserInfo(currUserId); 37613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (currUserInfo != null && currUserInfo.isGuest()) { 37713a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky showExitGuestDialog(currUserId, record.resolveId()); 37813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky return; 37913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 38013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 38113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky 382e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos switchToUserId(id); 383e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 384e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 385caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov public void switchTo(int userId) { 386caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov final int count = mUsers.size(); 387caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov for (int i = 0; i < count; ++i) { 388caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov UserRecord record = mUsers.get(i); 389caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov if (record.info != null && record.info.id == userId) { 390caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov switchTo(record); 391caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov return; 392caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 393caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 394caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 395caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov Log.e(TAG, "Couldn't switch to user, id=" + userId); 396caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 397caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 3988ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi public int getSwitchableUserCount() { 3998ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi int count = 0; 4008ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi final int N = mUsers.size(); 4018ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi for (int i = 0; i < N; ++i) { 4028ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi UserRecord record = mUsers.get(i); 4038ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi if (record.info != null && record.info.supportsSwitchTo()) { 4048ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi count++; 4058ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4068ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4078ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi return count; 4088ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4098ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi 41013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void switchToUserId(int id) { 41100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos try { 41288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos pauseRefreshUsers(); 413dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka ActivityManager.getService().switchUser(id); 41400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } catch (RemoteException e) { 41500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos Log.e(TAG, "Couldn't switch user.", e); 41600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 41700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 41800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 4195005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private void showExitGuestDialog(int id) { 42013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky int newId = UserHandle.USER_SYSTEM; 42113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) { 42213a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser); 42313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) { 42413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky newId = info.id; 42513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 42613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 42713a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky showExitGuestDialog(id, newId); 42813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 42913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky 43013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void showExitGuestDialog(int id, int targetId) { 4315005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4325005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4335005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 43413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky mExitGuestDialog = new ExitGuestDialog(mContext, id, targetId); 4355005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.show(); 4365005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4375005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 43892c91412ba099f5b5d17a7e28123629a1f7410c8Muyuan Li public void showAddUserDialog() { 4390c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (mAddUserDialog != null && mAddUserDialog.isShowing()) { 4400c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.cancel(); 4410c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4420c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog = new AddUserDialog(mContext); 4430c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.show(); 4440c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4450c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 44613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void exitGuest(int id, int targetId) { 44713a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky switchToUserId(targetId); 448e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos mUserManager.removeUser(id); 449e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 450e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 451523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void listenForCallState() { 452705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk TelephonyManager.from(mContext).listen(mPhoneStateListener, 453705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk PhoneStateListener.LISTEN_CALL_STATE); 454523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 455523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 456705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 457705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private int mCallState; 458705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 459705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk @Override 460705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk public void onCallStateChanged(int state, String incomingNumber) { 461705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (mCallState == state) return; 462705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (DEBUG) Log.v(TAG, "Call state changed: " + state); 463705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk mCallState = state; 464705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk int currentUserId = ActivityManager.getCurrentUser(); 465705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk UserInfo userInfo = mUserManager.getUserInfo(currentUserId); 466705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (userInfo != null && userInfo.isGuest()) { 467705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk showGuestNotification(currentUserId); 468705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 469705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk refreshUsers(UserHandle.USER_NULL); 470705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 471705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk }; 472705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 47300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private BroadcastReceiver mReceiver = new BroadcastReceiver() { 47400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 47500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void onReceive(Context context, Intent intent) { 4765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (DEBUG) { 4775005244f10442e75c1f48973fdddce5facf3f360Adrian Roos Log.v(TAG, "Broadcast: a=" + intent.getAction() 4785005244f10442e75c1f48973fdddce5facf3f360Adrian Roos + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); 4795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 48088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 48188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos boolean unpauseRefreshUsers = false; 48288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos int forcePictureLoadForId = UserHandle.USER_NULL; 48388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 484f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { 485f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov int currentUser = ActivityManager.getCurrentUser(); 486f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentUser); 487f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 488f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showExitGuestDialog(currentUser); 489f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 490f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov return; 49180996bbf40ff192117c391074ed2f9b2cde4e69aAdrian Roos } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) { 4921b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia logoutCurrentUser(); 49388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 4945005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = null; 4975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4985005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 49900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 5007cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen final UserInfo userInfo = mUserManager.getUserInfo(currentId); 50100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int N = mUsers.size(); 50200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < N; i++) { 50300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord record = mUsers.get(i); 504e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.info == null) continue; 50500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean shouldBeCurrent = record.info.id == currentId; 50600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isCurrent != shouldBeCurrent) { 50700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent)); 50800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 50970441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos if (shouldBeCurrent && !record.isGuest) { 51070441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos mLastNonGuestUser = record.info.id; 51170441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 5127cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) { 513ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Immediately remove restricted records in case the AsyncTask is too slow. 514ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mUsers.remove(i); 515ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos i--; 516ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 51700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 51800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 519860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 5203c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Disconnect from the old secondary user's service 5213c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson if (mSecondaryUser != UserHandle.USER_NULL) { 5223c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.stopServiceAsUser(mSecondaryUserServiceIntent, 5233c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(mSecondaryUser)); 5243c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = UserHandle.USER_NULL; 5253c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5263c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Connect to the new secondary user's service (purely to ensure that a persistent 5273c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // SystemUI application is created for that user) 528ec015d5cb510d26d4e951feb240be8025f477ff5Xiaohui Chen if (userInfo != null && userInfo.id != UserHandle.USER_SYSTEM) { 5293c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.startServiceAsUser(mSecondaryUserServiceIntent, 5303c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(userInfo.id)); 5313c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = userInfo.id; 5323c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5333c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 534860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest() 535860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen && userInfo.id != UserHandle.USER_SYSTEM) { 536860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen showLogoutNotification(currentId); 537860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 538ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 539ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov showGuestNotification(currentId); 540ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov } 54188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos unpauseRefreshUsers = true; 54288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { 543e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 544e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos UserHandle.USER_NULL); 54507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { 54607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov // Unlocking the system user may require a refresh 54707140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 54807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (userId != UserHandle.USER_SYSTEM) { 54907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return; 55007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 551e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 552e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(forcePictureLoadForId); 55388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (unpauseRefreshUsers) { 55488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mUnpauseRefreshUsers.run(); 55588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 55600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 557f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 558860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private void showLogoutNotification(int userId) { 559860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext, 560860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM); 561e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos Notification.Builder builder = new Notification.Builder(mContext) 562860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setVisibility(Notification.VISIBILITY_SECRET) 563860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setPriority(Notification.PRIORITY_MIN) 564860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setSmallIcon(R.drawable.ic_person) 565860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentTitle(mContext.getString(R.string.user_logout_notification_title)) 566860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setContentText(mContext.getString(R.string.user_logout_notification_text)) 56752408f4fb5dab950847aa12e3bea44399ccd0d6eFyodor Kupolov .setContentIntent(logoutPI) 568ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov .setOngoing(true) 569860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .setShowWhen(false) 570860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen .addAction(R.drawable.ic_delete, 571860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen mContext.getString(R.string.user_logout_notification_action), 572e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos logoutPI); 573e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 5745e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER, 5755e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren SystemMessage.NOTE_LOGOUT_USER, builder.build(), new UserHandle(userId)); 576860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 57700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 57800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 579523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void showGuestNotification(int guestUserId) { 580523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 581523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Disable 'Remove guest' action if cannot switch users right now 582523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext, 583523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null; 584523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 585e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos Notification.Builder builder = new Notification.Builder(mContext) 586523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setVisibility(Notification.VISIBILITY_SECRET) 587523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setPriority(Notification.PRIORITY_MIN) 588523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setSmallIcon(R.drawable.ic_person) 589523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentTitle(mContext.getString(R.string.guest_notification_title)) 590523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentText(mContext.getString(R.string.guest_notification_text)) 591523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setContentIntent(removeGuestPI) 592523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .setShowWhen(false) 593523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov .addAction(R.drawable.ic_delete, 594523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov mContext.getString(R.string.guest_notification_remove_action), 595e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos removeGuestPI); 596e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 5975e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, 5985e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren SystemMessage.NOTE_REMOVE_GUEST, builder.build(), new UserHandle(guestUserId)); 599523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 600523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 60188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Runnable mUnpauseRefreshUsers = new Runnable() { 60288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos @Override 60388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public void run() { 60488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.removeCallbacks(this); 60588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = false; 60688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos refreshUsers(UserHandle.USER_NULL); 60788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 60888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos }; 60988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 610ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 6112daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public void onChange(boolean selfChange) { 6122daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), 6132daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; 614ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), 615ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; 6162daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk refreshUsers(UserHandle.USER_NULL); 6172daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 6182daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 6192daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 62000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 62100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.println("UserSwitcherController state:"); 62270441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos pw.println(" mLastNonGuestUser=" + mLastNonGuestUser); 62300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" mUsers.size="); pw.println(mUsers.size()); 62400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < mUsers.size(); i++) { 62500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserRecord u = mUsers.get(i); 62600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" "); pw.println(u.toString()); 62700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 62800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 62900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 63057cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos public String getCurrentUserName(Context context) { 63157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (mUsers.isEmpty()) return null; 63257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos UserRecord item = mUsers.get(0); 63357cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item == null || item.info == null) return null; 63457cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item.isGuest) return context.getString(R.string.guest_nickname); 63557cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos return item.info.name; 63657cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos } 63757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos 638d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos public void onDensityOrFontScaleChanged() { 639d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos refreshUsers(UserHandle.USER_ALL); 640d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos } 641d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos 6428852905b0b3837e326127c6dfef6f699124ce715Jason Monk @VisibleForTesting 6438852905b0b3837e326127c6dfef6f699124ce715Jason Monk public void addAdapter(WeakReference<BaseUserAdapter> adapter) { 6448852905b0b3837e326127c6dfef6f699124ce715Jason Monk mAdapters.add(adapter); 6458852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 6468852905b0b3837e326127c6dfef6f699124ce715Jason Monk 6478852905b0b3837e326127c6dfef6f699124ce715Jason Monk @VisibleForTesting 6488852905b0b3837e326127c6dfef6f699124ce715Jason Monk public KeyguardMonitor getKeyguardMonitor() { 6498852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mKeyguardMonitor; 6508852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 6518852905b0b3837e326127c6dfef6f699124ce715Jason Monk 6528852905b0b3837e326127c6dfef6f699124ce715Jason Monk @VisibleForTesting 6538852905b0b3837e326127c6dfef6f699124ce715Jason Monk public ArrayList<UserRecord> getUsers() { 6548852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mUsers; 6558852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 6568852905b0b3837e326127c6dfef6f699124ce715Jason Monk 65700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static abstract class BaseUserAdapter extends BaseAdapter { 65800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 65900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserSwitcherController mController; 66000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected BaseUserAdapter(UserSwitcherController controller) { 66200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController = controller; 6638852905b0b3837e326127c6dfef6f699124ce715Jason Monk controller.addAdapter(new WeakReference<>(this)); 66400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 66500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 66700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getCount() { 6688852905b0b3837e326127c6dfef6f699124ce715Jason Monk boolean secureKeyguardShowing = mController.getKeyguardMonitor().isShowing() 6698852905b0b3837e326127c6dfef6f699124ce715Jason Monk && mController.getKeyguardMonitor().isSecure() 6708852905b0b3837e326127c6dfef6f699124ce715Jason Monk && !mController.getKeyguardMonitor().canSkipBouncer(); 671ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (!secureKeyguardShowing) { 6728852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mController.getUsers().size(); 673ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 674ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // The lock screen is secure and showing. Filter out restricted records. 6758852905b0b3837e326127c6dfef6f699124ce715Jason Monk final int N = mController.getUsers().size(); 676ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos int count = 0; 677ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos for (int i = 0; i < N; i++) { 6788852905b0b3837e326127c6dfef6f699124ce715Jason Monk if (mController.getUsers().get(i).isRestricted) { 679ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos break; 680ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else { 681ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos count++; 682ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 683ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 684ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return count; 68500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 68600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 68700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 68800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord getItem(int position) { 6898852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mController.getUsers().get(position); 69000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 69100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 69200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 69300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public long getItemId(int position) { 694e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return position; 69500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 69600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 69700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 69800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController.switchTo(record); 69900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 700e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 701e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos public String getName(Context context, UserRecord item) { 702e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isGuest) { 703e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isCurrent) { 704e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString(R.string.guest_exit_guest); 705e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 706e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString( 707e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); 708e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 709ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (item.isAddUser) { 710ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getString(R.string.user_add_user); 711e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 712e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return item.info.name; 713e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 714e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 715723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos 716ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public Drawable getDrawable(Context context, UserRecord item) { 717ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (item.isAddUser) { 718ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getDrawable(R.drawable.ic_add_circle_qs); 719ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 720aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return UserIcons.getDefaultUserIcon(item.resolveId(), /* light= */ true); 721ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 722844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos 723844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos public void refresh() { 724844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos mController.refreshUsers(UserHandle.USER_NULL); 725844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos } 72600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 72700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 728a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) { 729ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext, 730ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser()); 731ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext, 732ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) { 7331c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = true; 734ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka record.enforcedAdmin = admin; 7351c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } else { 7361c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = false; 7371c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.enforcedAdmin = null; 7381c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7391c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7401c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 7411c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public void startActivity(Intent intent) { 7421c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter.startActivity(intent, true); 7431c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7441c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 74500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static final class UserRecord { 74600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final UserInfo info; 74700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final Bitmap picture; 74800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isGuest; 74900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isCurrent; 750ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isAddUser; 751ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos /** If true, the record is only visible to the owner and only when unlocked. */ 752ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isRestricted; 7531c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public boolean isDisabledByAdmin; 7541c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public EnforcedAdmin enforcedAdmin; 75507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov public boolean isSwitchToEnabled; 75600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 757ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, 75807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov boolean isAddUser, boolean isRestricted, boolean isSwitchToEnabled) { 75900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.info = info; 76000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.picture = picture; 76100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isGuest = isGuest; 76200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isCurrent = isCurrent; 763ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isAddUser = isAddUser; 764ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isRestricted = isRestricted; 76507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov this.isSwitchToEnabled = isSwitchToEnabled; 76600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 76700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 76800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord copyWithIsCurrent(boolean _isCurrent) { 76907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted, 77007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov isSwitchToEnabled); 77100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 77200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 773aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky public int resolveId() { 774aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky if (isGuest || info == null) { 775aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return UserHandle.USER_NULL; 776aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 777aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return info.id; 778aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 779aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky 78000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public String toString() { 78100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos StringBuilder sb = new StringBuilder(); 78200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("UserRecord("); 78300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info != null) { 78407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append("name=\"").append(info.name).append("\" id=").append(info.id); 78500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 786ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) { 787ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add guest placeholder>"); 788ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (isAddUser) { 789ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add user placeholder>"); 790ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 79100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 792ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) sb.append(" <isGuest>"); 793ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isAddUser) sb.append(" <isAddUser>"); 794ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isCurrent) sb.append(" <isCurrent>"); 795ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (picture != null) sb.append(" <hasPicture>"); 796ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isRestricted) sb.append(" <isRestricted>"); 7971c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka if (isDisabledByAdmin) { 7981c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka sb.append(" <isDisabledByAdmin>"); 79907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" enforcedAdmin=").append(enforcedAdmin); 80007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 80107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (isSwitchToEnabled) { 80207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" <isSwitchToEnabled>"); 8031c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 80400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append(')'); 80500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return sb.toString(); 80600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 80700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 80800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 80946767b77c004a3541c614f8e21d6a871dd148e54Jason Monk public final DetailAdapter userDetailAdapter = new DetailAdapter() { 81076c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS); 81100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 81200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 813c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk public CharSequence getTitle() { 814c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk return mContext.getString(R.string.quick_settings_user_title); 81500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 81600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 81700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 81800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public View createDetailView(Context context, View convertView, ViewGroup parent) { 8191940892d891c1d2538f51608b6618af646ab7481Adrian Roos UserDetailView v; 82000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (!(convertView instanceof UserDetailView)) { 8211940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = UserDetailView.inflate(context, parent, false); 82200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos v.createAndSetAdapter(UserSwitcherController.this); 8231940892d891c1d2538f51608b6618af646ab7481Adrian Roos } else { 8241940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = (UserDetailView) convertView; 82500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 826844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos v.refreshAdapter(); 82700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return v; 82800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 82900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 83000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 83100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Intent getSettingsIntent() { 83200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return USER_SETTINGS_INTENT; 83300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 83400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 83500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 83600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Boolean getToggleState() { 83700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 83800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 83900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 84000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 84100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void setToggleState(boolean state) { 84200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 843457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 844457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 845457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 846f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren return MetricsEvent.QS_USERDETAIL; 847457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 84800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 8495005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 850ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { 851ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos @Override 852ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public void onKeyguardChanged() { 853ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos notifyAdapters(); 854ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 855ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }; 856ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 8575005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final class ExitGuestDialog extends SystemUIDialog implements 8585005244f10442e75c1f48973fdddce5facf3f360Adrian Roos DialogInterface.OnClickListener { 8595005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8605005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final int mGuestId; 86113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky private final int mTargetId; 8625005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 86313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky public ExitGuestDialog(Context context, int guestId, int targetId) { 8645005244f10442e75c1f48973fdddce5facf3f360Adrian Roos super(context); 8655005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setTitle(R.string.guest_exit_guest_dialog_title); 8665005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); 8675005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 868e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(android.R.string.cancel), this); 8695005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 870e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(R.string.guest_exit_guest_dialog_remove), this); 8715005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setCanceledOnTouchOutside(false); 8725005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestId = guestId; 87313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky mTargetId = targetId; 8745005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8755005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos @Override 8775005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public void onClick(DialogInterface dialog, int which) { 8785005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (which == BUTTON_NEGATIVE) { 8795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos cancel(); 8805005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } else { 8815005244f10442e75c1f48973fdddce5facf3f360Adrian Roos dismiss(); 88213a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky exitGuest(mGuestId, mTargetId); 8835005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8845005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8855005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 8860c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 8870c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private final class AddUserDialog extends SystemUIDialog implements 8880c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos DialogInterface.OnClickListener { 8890c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 8900c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public AddUserDialog(Context context) { 8910c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos super(context); 8920c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setTitle(R.string.user_add_user_title); 8930c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setMessage(context.getString(R.string.user_add_user_message_short)); 8940c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 8950c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.cancel), this); 8960c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 8970c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.ok), this); 8980c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 8990c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 9000c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos @Override 9010c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public void onClick(DialogInterface dialog, int which) { 9020c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (which == BUTTON_NEGATIVE) { 9030c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos cancel(); 9040c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } else { 9050c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos dismiss(); 906ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu if (ActivityManager.isUserAMonkey()) { 907ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu return; 908ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu } 909cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen UserInfo user = mUserManager.createUser( 910f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext.getString(R.string.user_new_user_name), 0 /* flags */); 911f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (user == null) { 912f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create user, most likely because there are too many, but we haven't 913f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // been able to reload the list yet. 914f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 915f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 916f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos int id = user.id; 91764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 91864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina id, /* light= */ false)); 91964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina mUserManager.setUserIcon(id, icon); 9200c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos switchToUserId(id); 9210c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 9220c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 9230c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 92400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos} 925