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 21334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monkimport android.R.attr; 2200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManager; 235005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.app.Dialog; 24f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.Notification; 25f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.NotificationManager; 26f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.PendingIntent; 2700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.BroadcastReceiver; 2800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Context; 295005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.content.DialogInterface; 3000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Intent; 3100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.IntentFilter; 3200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.pm.UserInfo; 332daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.database.ContentObserver; 3400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.graphics.Bitmap; 35334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monkimport android.graphics.PorterDuff.Mode; 36ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roosimport android.graphics.drawable.Drawable; 3700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.AsyncTask; 382daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.os.Handler; 3900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.RemoteException; 40e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.os.UserHandle; 4100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.UserManager; 422daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.provider.Settings; 43523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.PhoneStateListener; 44523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.TelephonyManager; 4500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log; 46e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray; 4788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseBooleanArray; 4800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View; 4900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup; 5000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter; 5100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 52383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 538852905b0b3837e326127c6dfef6f699124ce715Jason Monkimport com.android.internal.annotations.VisibleForTesting; 545e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wrenimport com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 5564d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 561c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils; 57334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monkimport com.android.settingslib.Utils; 589c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monkimport com.android.systemui.Dependency; 5964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver; 6064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R; 61e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roosimport com.android.systemui.SystemUI; 623c2c34bb039e92d68f466b7d194cbbe8241d8d60Winsonimport com.android.systemui.SystemUISecondaryUserService; 63e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monkimport com.android.systemui.plugins.qs.DetailAdapter; 6464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView; 65ec34da8f6f31c5ee1e543c0c7999a067487e0ce9Jason Monkimport com.android.systemui.plugins.ActivityStarter; 6664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog; 678e032e15e6b1b6a2f44fd3d5063ee83f45d71189Dan Sandlerimport com.android.systemui.util.NotificationChannels; 6864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina 6900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor; 7000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter; 7100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference; 7200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList; 7300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List; 7400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 7500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/** 7600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Keeps a list of all users on the device for user switching. 7700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 7800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospublic class UserSwitcherController { 7900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 8000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private static final String TAG = "UserSwitcherController"; 815005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private static final boolean DEBUG = false; 822daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = 832daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk "lockscreenSimpleUserSwitcher"; 84f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST"; 85860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String ACTION_LOGOUT_USER = "com.android.systemui.LOGOUT_USER"; 8688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000; 8700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 88d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String TAG_REMOVE_GUEST = "remove_guest"; 89860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private static final String TAG_LOGOUT_USER = "logout_user"; 90860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 91d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; 92d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani 9313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected final Context mContext; 9413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected final UserManager mUserManager; 9500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); 965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final GuestResumeSessionReceiver mGuestResumeSessionReceiver 975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos = new GuestResumeSessionReceiver(); 98ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor mKeyguardMonitor; 9913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected final Handler mHandler; 1001c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka private final ActivityStarter mActivityStarter; 10100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 10200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private ArrayList<UserRecord> mUsers = new ArrayList<>(); 1035005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private Dialog mExitGuestDialog; 1040c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private Dialog mAddUserDialog; 1057cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen private int mLastNonGuestUser = UserHandle.USER_SYSTEM; 10637c76807a047193338e3af317fb39373d69c7561Evan Rosky private boolean mResumeUserOnGuestLogout = true; 107ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mSimpleUserSwitcher; 108ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mAddUsersWhenLocked; 10988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private boolean mPauseRefreshUsers; 1103c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private int mSecondaryUser = UserHandle.USER_NULL; 1113c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson private Intent mSecondaryUserServiceIntent; 11288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); 11300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 11488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, 1151c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka Handler handler, ActivityStarter activityStarter) { 11600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mContext = context; 1175005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestResumeSessionReceiver.register(context); 118ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mKeyguardMonitor = keyguardMonitor; 11988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler = handler; 1201c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter = activityStarter; 12100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserManager = UserManager.get(context); 12200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos IntentFilter filter = new IntentFilter(); 12300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_ADDED); 12400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_REMOVED); 12500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 12600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 127ad2e4bf9f36cf612db6c397feca8effb125ee541Amith Yamasani filter.addAction(Intent.ACTION_USER_STOPPED); 12807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov filter.addAction(Intent.ACTION_USER_UNLOCKED); 1297cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 130e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos null /* permission */, null /* scheduler */); 1312daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 1323c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class); 1333c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 134d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter = new IntentFilter(); 135d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani filter.addAction(ACTION_REMOVE_GUEST); 136860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen filter.addAction(ACTION_LOGOUT_USER); 1375891a346abbde5bfe95a52633d05533406cc6a2eAmith Yamasani mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 138d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani PERMISSION_SELF, null /* scheduler */); 139ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1402daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mContext.getContentResolver().registerContentObserver( 1412daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, 142ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 143ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mContext.getContentResolver().registerContentObserver( 144ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, 145ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 14607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov mContext.getContentResolver().registerContentObserver( 14707140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.getUriFor( 14807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED), 14907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov true, mSettingsObserver); 150ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Fetch initial values. 151ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver.onChange(false); 152ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 153ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos keyguardMonitor.addCallback(mCallback); 154523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov listenForCallState(); 1552daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 156e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(UserHandle.USER_NULL); 15700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 15800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 159e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos /** 160e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * Refreshes users from UserManager. 161e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 162e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * The pictures are only loaded if they have not been loaded yet. 163e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 164e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * @param forcePictureLoadForId forces the picture of the given user to be reloaded. 165e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos */ 16695ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani @SuppressWarnings("unchecked") 167e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void refreshUsers(int forcePictureLoadForId) { 16888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")"); 16988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (forcePictureLoadForId != UserHandle.USER_NULL) { 17088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.put(forcePictureLoadForId, true); 17188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 17288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 17388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (mPauseRefreshUsers) { 17488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos return; 17588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 176c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos 177d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos boolean forceAllUsers = mForcePictureLoadForUserId.get(UserHandle.USER_ALL); 178c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); 179c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos final int N = mUsers.size(); 180c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos for (int i = 0; i < N; i++) { 181c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos UserRecord r = mUsers.get(i); 182d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos if (r == null || r.picture == null || r.info == null || forceAllUsers 183d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos || mForcePictureLoadForUserId.get(r.info.id)) { 184c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos continue; 185e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 186c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos bitmaps.put(r.info.id, r.picture); 187e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 18888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mForcePictureLoadForUserId.clear(); 189e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 190ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final boolean addUsersWhenLocked = mAddUsersWhenLocked; 191e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { 192e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos @SuppressWarnings("unchecked") 19300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 194e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { 195e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos final SparseArray<Bitmap> bitmaps = params[0]; 19600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos List<UserInfo> infos = mUserManager.getUsers(true); 19700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (infos == null) { 19800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 19900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 20000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ArrayList<UserRecord> records = new ArrayList<>(infos.size()); 20100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int currentId = ActivityManager.getCurrentUser(); 202523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 2037cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserInfo currentUserInfo = null; 20400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord guestRecord = null; 20500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 20600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (UserInfo info : infos) { 20700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean isCurrent = currentId == info.id; 2087cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (isCurrent) { 2097cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen currentUserInfo = info; 2107cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } 211523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean switchToEnabled = canSwitchUsers || isCurrent; 2121ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isEnabled()) { 2131ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (info.isGuest()) { 214523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Tapping guest icon triggers remove and a user switch therefore 215523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // the icon shouldn't be enabled even if the user is current 2161ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova guestRecord = new UserRecord(info, null /* picture */, 2171ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova true /* isGuest */, isCurrent, false /* isAddUser */, 218523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isRestricted */, canSwitchUsers); 2191ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } else if (info.supportsSwitchToByUser()) { 2201ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova Bitmap picture = bitmaps.get(info.id); 2211ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture == null) { 2221ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova picture = mUserManager.getUserIcon(info.id); 2231ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova 2241ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova if (picture != null) { 225aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky int avatarSize = mContext.getResources() 226aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky .getDimensionPixelSize(R.dimen.max_avatar_size); 227aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture = Bitmap.createScaledBitmap( 228aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky picture, avatarSize, avatarSize, true); 2291ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova } 230cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos } 2311ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova int index = isCurrent ? 0 : records.size(); 2321ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova records.add(index, new UserRecord(info, picture, false /* isGuest */, 2331ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova isCurrent, false /* isAddUser */, false /* isRestricted */, 2341ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova switchToEnabled)); 2354d75c079f35d85b687d8349e5e2940447d01198eDan Sandler } 23600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 239a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction( 240a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); 2417cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean currentUserCanCreateUsers = currentUserInfo != null 2427cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && (currentUserInfo.isAdmin() 243a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka || currentUserInfo.id == UserHandle.USER_SYSTEM) 244a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka && systemCanCreateUsers; 245a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked; 246a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) 247ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos && guestRecord == null; 248a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) 24995ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani && mUserManager.canAddMoreUsers(); 250ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean createIsRestricted = !addUsersWhenLocked; 251ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 2522daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (!mSimpleUserSwitcher) { 2532daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (guestRecord == null) { 254ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (canCreateGuest) { 2551c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka guestRecord = new UserRecord(null /* info */, null /* picture */, 256ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, false /* isCurrent */, 257523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov false /* isAddUser */, createIsRestricted, canSwitchUsers); 258a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(guestRecord); 2591c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(guestRecord); 260ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 2612daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } else { 262bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = guestRecord.isCurrent ? 0 : records.size(); 263bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, guestRecord); 2642daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 26500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 26600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 267092be7de024b8b1a050ad247a016febc795546afJason Monk if (!mSimpleUserSwitcher && canCreateUser) { 2681c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */, 269ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isGuest */, false /* isCurrent */, true /* isAddUser */, 270523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov createIsRestricted, canSwitchUsers); 271a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka checkIfAddUserDisallowedByAdminOnly(addUserRecord); 2721c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka records.add(addUserRecord); 273ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 274ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 27500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return records; 27600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 27800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 27900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected void onPostExecute(ArrayList<UserRecord> userRecords) { 28000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (userRecords != null) { 28100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers = userRecords; 28200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 28300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 28400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 285ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }.execute((SparseArray) bitmaps); 28600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 28700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 28888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private void pauseRefreshUsers() { 28988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (!mPauseRefreshUsers) { 29088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS); 29188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = true; 29288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 29388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 29488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 29500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private void notifyAdapters() { 29600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = mAdapters.size() - 1; i >= 0; i--) { 29700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos BaseUserAdapter adapter = mAdapters.get(i).get(); 29800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (adapter != null) { 29900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos adapter.notifyDataSetChanged(); 30000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 30100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mAdapters.remove(i); 30200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 30300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 30400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 30500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 3062daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public boolean isSimpleUserSwitcher() { 3072daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk return mSimpleUserSwitcher; 3082daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 3092daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 310cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public boolean useFullscreenUserSwitcher() { 311cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Use adb to override: 312cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off. 313cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on. 314cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Restart SystemUI or adb reboot. 315cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int DEFAULT = -1; 316cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia final int overrideUseFullscreenUserSwitcher = 317cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Settings.System.getInt(mContext.getContentResolver(), 318cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia "enable_fullscreen_user_switcher", DEFAULT); 319cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (overrideUseFullscreenUserSwitcher != DEFAULT) { 320cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return overrideUseFullscreenUserSwitcher != 0; 321cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 322cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia // Otherwise default to the build setting. 32340f9dabaa880eaff54099a3763224b241a6668e6Xiyuan Xia return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher); 324cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 325cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 32637c76807a047193338e3af317fb39373d69c7561Evan Rosky public void setResumeUserOnGuestLogout(boolean resume) { 32737c76807a047193338e3af317fb39373d69c7561Evan Rosky mResumeUserOnGuestLogout = resume; 32837c76807a047193338e3af317fb39373d69c7561Evan Rosky } 32937c76807a047193338e3af317fb39373d69c7561Evan Rosky 3301b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia public void logoutCurrentUser() { 3311b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia int currentUser = ActivityManager.getCurrentUser(); 3321b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia if (currentUser != UserHandle.USER_SYSTEM) { 333b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov pauseRefreshUsers(); 334b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov ActivityManager.logoutCurrentUser(); 3351b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3361b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia } 3371b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia 338cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia public void removeUserId(int userId) { 339cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (userId == UserHandle.USER_SYSTEM) { 340cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia Log.w(TAG, "User " + userId + " could not removed."); 341cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia return; 342cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 343cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (ActivityManager.getCurrentUser() == userId) { 344cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia switchToUserId(UserHandle.USER_SYSTEM); 345cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 346cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia if (mUserManager.removeUser(userId)) { 347cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia refreshUsers(UserHandle.USER_NULL); 348cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 349cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia } 350cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia 35100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 35200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int id; 35300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isGuest && record.info == null) { 35400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos // No guest user. Create one. 355f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos UserInfo guest = mUserManager.createGuest( 356f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext, mContext.getString(R.string.guest_nickname)); 357f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (guest == null) { 358f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create guest, most likely because there already exists one, we just 359f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // haven't reloaded the user list yet. 360f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 361f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 362f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos id = guest.id; 363ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (record.isAddUser) { 3640c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos showAddUserDialog(); 3650c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos return; 36600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 36700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos id = record.info.id; 36800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 36900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 37013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky int currUserId = ActivityManager.getCurrentUser(); 37113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (currUserId == id) { 372e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.isGuest) { 3735005244f10442e75c1f48973fdddce5facf3f360Adrian Roos showExitGuestDialog(id); 374e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 37500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return; 37600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 37700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 37813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (UserManager.isGuestUserEphemeral()) { 37913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky // If switching from guest, we want to bring up the guest exit dialog instead of switching 38013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky UserInfo currUserInfo = mUserManager.getUserInfo(currUserId); 38113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (currUserInfo != null && currUserInfo.isGuest()) { 38213a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky showExitGuestDialog(currUserId, record.resolveId()); 38313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky return; 38413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 38513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 38613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky 387e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos switchToUserId(id); 388e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 389e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 390caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov public void switchTo(int userId) { 391caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov final int count = mUsers.size(); 392caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov for (int i = 0; i < count; ++i) { 393caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov UserRecord record = mUsers.get(i); 394caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov if (record.info != null && record.info.id == userId) { 395caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov switchTo(record); 396caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov return; 397caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 398caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 399caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 400caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov Log.e(TAG, "Couldn't switch to user, id=" + userId); 401caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov } 402caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov 4038ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi public int getSwitchableUserCount() { 4048ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi int count = 0; 4058ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi final int N = mUsers.size(); 4068ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi for (int i = 0; i < N; ++i) { 4078ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi UserRecord record = mUsers.get(i); 4088ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi if (record.info != null && record.info.supportsSwitchTo()) { 4098ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi count++; 4108ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4118ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4128ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi return count; 4138ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi } 4148ba446c9bad94e91cf83c579261298552d51d249Daniel Nishi 41513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void switchToUserId(int id) { 41600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos try { 41788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos pauseRefreshUsers(); 418dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka ActivityManager.getService().switchUser(id); 41900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } catch (RemoteException e) { 42000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos Log.e(TAG, "Couldn't switch user.", e); 42100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 42200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 42300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 4245005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private void showExitGuestDialog(int id) { 42513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky int newId = UserHandle.USER_SYSTEM; 42613a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) { 42713a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser); 42813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) { 42913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky newId = info.id; 43013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 43113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 43213a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky showExitGuestDialog(id, newId); 43313a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky } 43413a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky 43513a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void showExitGuestDialog(int id, int targetId) { 4365005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 4375005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 4385005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 43913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky mExitGuestDialog = new ExitGuestDialog(mContext, id, targetId); 4405005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.show(); 4415005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 4425005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 44392c91412ba099f5b5d17a7e28123629a1f7410c8Muyuan Li public void showAddUserDialog() { 4440c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (mAddUserDialog != null && mAddUserDialog.isShowing()) { 4450c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.cancel(); 4460c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4470c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog = new AddUserDialog(mContext); 4480c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.show(); 4490c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 4500c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 45113a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky protected void exitGuest(int id, int targetId) { 45213a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky switchToUserId(targetId); 453e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos mUserManager.removeUser(id); 454e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 455e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 456523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void listenForCallState() { 457705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk TelephonyManager.from(mContext).listen(mPhoneStateListener, 458705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk PhoneStateListener.LISTEN_CALL_STATE); 459523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 460523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 461705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 462705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk private int mCallState; 463705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 464705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk @Override 465705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk public void onCallStateChanged(int state, String incomingNumber) { 466705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (mCallState == state) return; 467705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (DEBUG) Log.v(TAG, "Call state changed: " + state); 468705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk mCallState = state; 469705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk int currentUserId = ActivityManager.getCurrentUser(); 470705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk UserInfo userInfo = mUserManager.getUserInfo(currentUserId); 471705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk if (userInfo != null && userInfo.isGuest()) { 472705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk showGuestNotification(currentUserId); 473705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 474705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk refreshUsers(UserHandle.USER_NULL); 475705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk } 476705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk }; 477705a4bc62341d70a9b75b28f68c64efc88321438Jason Monk 47800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private BroadcastReceiver mReceiver = new BroadcastReceiver() { 47900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 48000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void onReceive(Context context, Intent intent) { 4815005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (DEBUG) { 4825005244f10442e75c1f48973fdddce5facf3f360Adrian Roos Log.v(TAG, "Broadcast: a=" + intent.getAction() 4835005244f10442e75c1f48973fdddce5facf3f360Adrian Roos + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); 4845005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 48588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 48688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos boolean unpauseRefreshUsers = false; 48788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos int forcePictureLoadForId = UserHandle.USER_NULL; 48888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 489f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { 490f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov int currentUser = ActivityManager.getCurrentUser(); 491f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentUser); 492f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 493f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showExitGuestDialog(currentUser); 494f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 495f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov return; 49680996bbf40ff192117c391074ed2f9b2cde4e69aAdrian Roos } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) { 4971b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia logoutCurrentUser(); 49888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 4995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 5005005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 5015005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = null; 5025005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 5035005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 50400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 5057cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen final UserInfo userInfo = mUserManager.getUserInfo(currentId); 50600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int N = mUsers.size(); 50700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < N; i++) { 50800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord record = mUsers.get(i); 509e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.info == null) continue; 51000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean shouldBeCurrent = record.info.id == currentId; 51100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isCurrent != shouldBeCurrent) { 51200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent)); 51300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 51470441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos if (shouldBeCurrent && !record.isGuest) { 51570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos mLastNonGuestUser = record.info.id; 51670441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 5177cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) { 518ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Immediately remove restricted records in case the AsyncTask is too slow. 519ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mUsers.remove(i); 520ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos i--; 521ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 52200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 52300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 524860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 5253c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Disconnect from the old secondary user's service 5263c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson if (mSecondaryUser != UserHandle.USER_NULL) { 5273c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.stopServiceAsUser(mSecondaryUserServiceIntent, 5283c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(mSecondaryUser)); 5293c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = UserHandle.USER_NULL; 5303c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5313c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // Connect to the new secondary user's service (purely to ensure that a persistent 5323c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson // SystemUI application is created for that user) 533ec015d5cb510d26d4e951feb240be8025f477ff5Xiaohui Chen if (userInfo != null && userInfo.id != UserHandle.USER_SYSTEM) { 5343c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson context.startServiceAsUser(mSecondaryUserServiceIntent, 5353c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson UserHandle.of(userInfo.id)); 5363c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson mSecondaryUser = userInfo.id; 5373c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson } 5383c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson 539860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest() 540860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen && userInfo.id != UserHandle.USER_SYSTEM) { 541860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen showLogoutNotification(currentId); 542860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 543ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 544ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov showGuestNotification(currentId); 545ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov } 54688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos unpauseRefreshUsers = true; 54788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { 548e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 549e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos UserHandle.USER_NULL); 55007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { 55107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov // Unlocking the system user may require a refresh 55207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 55307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (userId != UserHandle.USER_SYSTEM) { 55407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return; 55507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 556e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 557e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(forcePictureLoadForId); 55888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos if (unpauseRefreshUsers) { 55988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mUnpauseRefreshUsers.run(); 56088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 56100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 562f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 563860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen private void showLogoutNotification(int userId) { 564860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext, 565860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen 0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM); 5661dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 5671dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.GENERAL) 5681dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_SECRET) 5691dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(R.drawable.ic_person) 5701dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(mContext.getString( 5711dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch R.string.user_logout_notification_title)) 5721dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(mContext.getString( 5731dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch R.string.user_logout_notification_text)) 5741dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(logoutPI) 5751dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setOngoing(true) 5761dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setShowWhen(false) 5771dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .addAction(R.drawable.ic_delete, 5781dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch mContext.getString(R.string.user_logout_notification_action), 5791dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch logoutPI); 580e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 5815e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER, 5825e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren SystemMessage.NOTE_LOGOUT_USER, builder.build(), new UserHandle(userId)); 583860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen } 58400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 58500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 586523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov private void showGuestNotification(int guestUserId) { 587523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov boolean canSwitchUsers = mUserManager.canSwitchUsers(); 588523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov // Disable 'Remove guest' action if cannot switch users right now 589523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext, 590523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null; 591523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 5921dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 5931dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.GENERAL) 5941dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_SECRET) 5951dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(R.drawable.ic_person) 5961dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(mContext.getString(R.string.guest_notification_title)) 5971dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(mContext.getString(R.string.guest_notification_text)) 5981dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(removeGuestPI) 5991dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setShowWhen(false) 6001dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .addAction(R.drawable.ic_delete, 6011dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch mContext.getString(R.string.guest_notification_remove_action), 6021dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch removeGuestPI); 603e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 6045e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, 6055e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren SystemMessage.NOTE_REMOVE_GUEST, builder.build(), new UserHandle(guestUserId)); 606523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov } 607523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov 60888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos private final Runnable mUnpauseRefreshUsers = new Runnable() { 60988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos @Override 61088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos public void run() { 61188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mHandler.removeCallbacks(this); 61288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos mPauseRefreshUsers = false; 61388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos refreshUsers(UserHandle.USER_NULL); 61488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos } 61588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos }; 61688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos 617ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 6182daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public void onChange(boolean selfChange) { 6192daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), 6202daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; 621ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), 622ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; 6232daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk refreshUsers(UserHandle.USER_NULL); 6242daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 6252daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 6262daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 62700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 62800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.println("UserSwitcherController state:"); 62970441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos pw.println(" mLastNonGuestUser=" + mLastNonGuestUser); 63000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" mUsers.size="); pw.println(mUsers.size()); 63100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < mUsers.size(); i++) { 63200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserRecord u = mUsers.get(i); 63300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" "); pw.println(u.toString()); 63400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 63500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 63600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 63757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos public String getCurrentUserName(Context context) { 63857cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (mUsers.isEmpty()) return null; 63957cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos UserRecord item = mUsers.get(0); 64057cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item == null || item.info == null) return null; 64157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item.isGuest) return context.getString(R.string.guest_nickname); 64257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos return item.info.name; 64357cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos } 64457cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos 645d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos public void onDensityOrFontScaleChanged() { 646d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos refreshUsers(UserHandle.USER_ALL); 647d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos } 648d390b893eafae634844d7b8b84efaa7baa199119Adrian Roos 6498852905b0b3837e326127c6dfef6f699124ce715Jason Monk @VisibleForTesting 6508852905b0b3837e326127c6dfef6f699124ce715Jason Monk public void addAdapter(WeakReference<BaseUserAdapter> adapter) { 6518852905b0b3837e326127c6dfef6f699124ce715Jason Monk mAdapters.add(adapter); 6528852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 6538852905b0b3837e326127c6dfef6f699124ce715Jason Monk 6548852905b0b3837e326127c6dfef6f699124ce715Jason Monk @VisibleForTesting 6558852905b0b3837e326127c6dfef6f699124ce715Jason Monk public ArrayList<UserRecord> getUsers() { 6568852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mUsers; 6578852905b0b3837e326127c6dfef6f699124ce715Jason Monk } 6588852905b0b3837e326127c6dfef6f699124ce715Jason Monk 65900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static abstract class BaseUserAdapter extends BaseAdapter { 66000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserSwitcherController mController; 6629c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk private final KeyguardMonitor mKeyguardMonitor; 66300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 66400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected BaseUserAdapter(UserSwitcherController controller) { 66500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController = controller; 6669c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); 6678852905b0b3837e326127c6dfef6f699124ce715Jason Monk controller.addAdapter(new WeakReference<>(this)); 66800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 66900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 670e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk public int getUserCount() { 671e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk boolean secureKeyguardShowing = mKeyguardMonitor.isShowing() 672e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk && mKeyguardMonitor.isSecure() 673e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk && !mKeyguardMonitor.canSkipBouncer(); 674e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk if (!secureKeyguardShowing) { 675e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk return mController.getUsers().size(); 676e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 677e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk // The lock screen is secure and showing. Filter out restricted records. 678e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk final int N = mController.getUsers().size(); 679e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk int count = 0; 680e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk for (int i = 0; i < N; i++) { 681e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk if (mController.getUsers().get(i).isGuest) continue; 682e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk if (mController.getUsers().get(i).isRestricted) { 683e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk break; 684e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } else { 685e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk count++; 686e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 687e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 688e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk return count; 689e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 690e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk 69100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 69200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getCount() { 6939c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk boolean secureKeyguardShowing = mKeyguardMonitor.isShowing() 6949c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk && mKeyguardMonitor.isSecure() 6959c7844cb91b43929d0a86b1c90aa1efb37f5463aJason Monk && !mKeyguardMonitor.canSkipBouncer(); 696ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (!secureKeyguardShowing) { 6978852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mController.getUsers().size(); 698ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 699ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // The lock screen is secure and showing. Filter out restricted records. 7008852905b0b3837e326127c6dfef6f699124ce715Jason Monk final int N = mController.getUsers().size(); 701ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos int count = 0; 702ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos for (int i = 0; i < N; i++) { 7038852905b0b3837e326127c6dfef6f699124ce715Jason Monk if (mController.getUsers().get(i).isRestricted) { 704ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos break; 705ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else { 706ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos count++; 707ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 708ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 709ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return count; 71000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 71100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 71200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 71300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord getItem(int position) { 7148852905b0b3837e326127c6dfef6f699124ce715Jason Monk return mController.getUsers().get(position); 71500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 71600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 71700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 71800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public long getItemId(int position) { 719e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return position; 72000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 72100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 72200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 72300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController.switchTo(record); 72400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 725e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 726e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos public String getName(Context context, UserRecord item) { 727e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isGuest) { 728e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isCurrent) { 729e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString(R.string.guest_exit_guest); 730e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 731e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString( 732e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); 733e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 734ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (item.isAddUser) { 735ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getString(R.string.user_add_user); 736e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 737e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return item.info.name; 738e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 739e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 740723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos 741ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public Drawable getDrawable(Context context, UserRecord item) { 742ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (item.isAddUser) { 743ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getDrawable(R.drawable.ic_add_circle_qs); 744ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 745334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk Drawable icon = UserIcons.getDefaultUserIcon(item.resolveId(), /* light= */ false); 746334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk if (item.isGuest) { 747334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk icon.setColorFilter(Utils.getColorAttr(context, android.R.attr.colorForeground), 748334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk Mode.SRC_IN); 749334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk } 750334b04b4d68e0126d57beba3171e6bcac88ede11Jason Monk return icon; 751ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 752844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos 753844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos public void refresh() { 754844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos mController.refreshUsers(UserHandle.USER_NULL); 755844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos } 75600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 75700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 758a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) { 759ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext, 760ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser()); 761ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext, 762ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) { 7631c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = true; 764ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka record.enforcedAdmin = admin; 7651c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } else { 7661c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.isDisabledByAdmin = false; 7671c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka record.enforcedAdmin = null; 7681c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7691c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7701c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 7711c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public void startActivity(Intent intent) { 7721c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka mActivityStarter.startActivity(intent, true); 7731c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 7741c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka 77500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static final class UserRecord { 77600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final UserInfo info; 77700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final Bitmap picture; 77800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isGuest; 77900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isCurrent; 780ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isAddUser; 781ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos /** If true, the record is only visible to the owner and only when unlocked. */ 782ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isRestricted; 7831c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public boolean isDisabledByAdmin; 7841c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka public EnforcedAdmin enforcedAdmin; 78507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov public boolean isSwitchToEnabled; 78600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 787ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, 78807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov boolean isAddUser, boolean isRestricted, boolean isSwitchToEnabled) { 78900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.info = info; 79000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.picture = picture; 79100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isGuest = isGuest; 79200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isCurrent = isCurrent; 793ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isAddUser = isAddUser; 794ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isRestricted = isRestricted; 79507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov this.isSwitchToEnabled = isSwitchToEnabled; 79600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 79700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 79800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord copyWithIsCurrent(boolean _isCurrent) { 79907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted, 80007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov isSwitchToEnabled); 80100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 80200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 803aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky public int resolveId() { 804aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky if (isGuest || info == null) { 805aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return UserHandle.USER_NULL; 806aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 807aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky return info.id; 808aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky } 809aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky 81000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public String toString() { 81100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos StringBuilder sb = new StringBuilder(); 81200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("UserRecord("); 81300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info != null) { 81407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append("name=\"").append(info.name).append("\" id=").append(info.id); 81500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 816ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) { 817ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add guest placeholder>"); 818ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (isAddUser) { 819ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add user placeholder>"); 820ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 82100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 822ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) sb.append(" <isGuest>"); 823ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isAddUser) sb.append(" <isAddUser>"); 824ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isCurrent) sb.append(" <isCurrent>"); 825ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (picture != null) sb.append(" <hasPicture>"); 826ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isRestricted) sb.append(" <isRestricted>"); 8271c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka if (isDisabledByAdmin) { 8281c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka sb.append(" <isDisabledByAdmin>"); 82907140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" enforcedAdmin=").append(enforcedAdmin); 83007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov } 83107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov if (isSwitchToEnabled) { 83207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov sb.append(" <isSwitchToEnabled>"); 8331c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 83400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append(')'); 83500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return sb.toString(); 83600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 83700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 83800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 83946767b77c004a3541c614f8e21d6a871dd148e54Jason Monk public final DetailAdapter userDetailAdapter = new DetailAdapter() { 84076c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS); 84100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 84200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 843c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk public CharSequence getTitle() { 844c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk return mContext.getString(R.string.quick_settings_user_title); 84500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 84600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 84700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 84800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public View createDetailView(Context context, View convertView, ViewGroup parent) { 8491940892d891c1d2538f51608b6618af646ab7481Adrian Roos UserDetailView v; 85000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (!(convertView instanceof UserDetailView)) { 8511940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = UserDetailView.inflate(context, parent, false); 85200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos v.createAndSetAdapter(UserSwitcherController.this); 8531940892d891c1d2538f51608b6618af646ab7481Adrian Roos } else { 8541940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = (UserDetailView) convertView; 85500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 856844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos v.refreshAdapter(); 85700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return v; 85800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 85900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 86000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 86100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Intent getSettingsIntent() { 86200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return USER_SETTINGS_INTENT; 86300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 86400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 86500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 86600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Boolean getToggleState() { 86700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 86800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 86900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 87000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 87100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void setToggleState(boolean state) { 87200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 873457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 874457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 875457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 876f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren return MetricsEvent.QS_USERDETAIL; 877457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 87800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 8795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 880ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { 881ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos @Override 882aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk public void onKeyguardShowingChanged() { 883e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi 884e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi // When Keyguard is going away, we don't need to update our items immediately which 885e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi // helps making the transition faster. 886e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi if (!mKeyguardMonitor.isShowing()) { 887e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi mHandler.post(UserSwitcherController.this::notifyAdapters); 888e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi } else { 889e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi notifyAdapters(); 890e549a8d62108c7c7dabedbf4e77b9a653781723bJorim Jaggi } 891ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 892ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }; 893ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 8945005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final class ExitGuestDialog extends SystemUIDialog implements 8955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos DialogInterface.OnClickListener { 8965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 8975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final int mGuestId; 89813a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky private final int mTargetId; 8995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 90013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky public ExitGuestDialog(Context context, int guestId, int targetId) { 9015005244f10442e75c1f48973fdddce5facf3f360Adrian Roos super(context); 9025005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setTitle(R.string.guest_exit_guest_dialog_title); 9035005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); 9045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 905e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(android.R.string.cancel), this); 9065005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 907e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(R.string.guest_exit_guest_dialog_remove), this); 9085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setCanceledOnTouchOutside(false); 9095005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestId = guestId; 91013a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky mTargetId = targetId; 9115005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 9125005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 9135005244f10442e75c1f48973fdddce5facf3f360Adrian Roos @Override 9145005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public void onClick(DialogInterface dialog, int which) { 9155005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (which == BUTTON_NEGATIVE) { 9165005244f10442e75c1f48973fdddce5facf3f360Adrian Roos cancel(); 9175005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } else { 9185005244f10442e75c1f48973fdddce5facf3f360Adrian Roos dismiss(); 91913a58a91d362e74933b3064a65be4bf4449cfdc4Evan Rosky exitGuest(mGuestId, mTargetId); 9205005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 9215005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 9225005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 9230c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 9240c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private final class AddUserDialog extends SystemUIDialog implements 9250c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos DialogInterface.OnClickListener { 9260c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 9270c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public AddUserDialog(Context context) { 9280c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos super(context); 9290c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setTitle(R.string.user_add_user_title); 9300c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setMessage(context.getString(R.string.user_add_user_message_short)); 9310c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 9320c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.cancel), this); 9330c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 9340c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.ok), this); 9350c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 9360c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 9370c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos @Override 9380c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public void onClick(DialogInterface dialog, int which) { 9390c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (which == BUTTON_NEGATIVE) { 9400c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos cancel(); 9410c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } else { 9420c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos dismiss(); 943ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu if (ActivityManager.isUserAMonkey()) { 944ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu return; 945ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu } 946cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen UserInfo user = mUserManager.createUser( 947f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext.getString(R.string.user_new_user_name), 0 /* flags */); 948f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (user == null) { 949f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create user, most likely because there are too many, but we haven't 950f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // been able to reload the list yet. 951f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 952f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 953f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos int id = user.id; 95464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 95564d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina id, /* light= */ false)); 95664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina mUserManager.setUserIcon(id, icon); 9570c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos switchToUserId(id); 9580c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 9590c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 9600c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 96100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos} 962