UserSwitcherController.java revision cfe64c8afa9f30d8874c72440c3992e79fdb60c9
100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/* 200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Copyright (C) 2014 The Android Open Source Project 300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * you may not use this file except in compliance with the License. 600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * You may obtain a copy of the License at 700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * http://www.apache.org/licenses/LICENSE-2.0 900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * 1000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Unless required by applicable law or agreed to in writing, software 1100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 1200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * See the License for the specific language governing permissions and 1400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * limitations under the License 1500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 1600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 1700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospackage com.android.systemui.statusbar.policy; 1800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 1900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManager; 2000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.app.ActivityManagerNative; 215005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.app.Dialog; 22f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.Notification; 23f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.NotificationManager; 24f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolovimport android.app.PendingIntent; 2500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.BroadcastReceiver; 2600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Context; 275005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.content.DialogInterface; 2800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Intent; 2900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.IntentFilter; 3000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.pm.UserInfo; 312daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.database.ContentObserver; 3200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.graphics.Bitmap; 33ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roosimport android.graphics.drawable.Drawable; 3400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.AsyncTask; 352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.os.Handler; 3600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.RemoteException; 37e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.os.UserHandle; 3800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.UserManager; 392daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.provider.Settings; 4000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log; 41e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray; 4200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View; 4300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup; 4400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter; 4500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 46457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wrenimport com.android.internal.logging.MetricsLogger; 4764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons; 4864d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.BitmapHelper; 4964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver; 5064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R; 5164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.QSTile; 5264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView; 5364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog; 5464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina 5500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor; 5600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter; 5700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference; 5800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList; 5900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List; 6000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 6100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/** 6200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Keeps a list of all users on the device for user switching. 6300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */ 6400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospublic class UserSwitcherController { 6500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 6600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private static final String TAG = "UserSwitcherController"; 675005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private static final boolean DEBUG = false; 682daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = 692daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk "lockscreenSimpleUserSwitcher"; 70f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST"; 7100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 7200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final Context mContext; 7300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final UserManager mUserManager; 7400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>(); 755005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final GuestResumeSessionReceiver mGuestResumeSessionReceiver 765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos = new GuestResumeSessionReceiver(); 77ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor mKeyguardMonitor; 7800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 7900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private ArrayList<UserRecord> mUsers = new ArrayList<>(); 805005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private Dialog mExitGuestDialog; 810c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private Dialog mAddUserDialog; 827cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen private int mLastNonGuestUser = UserHandle.USER_SYSTEM; 83ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mSimpleUserSwitcher; 84ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private boolean mAddUsersWhenLocked; 8500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 86ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor) { 8700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mContext = context; 885005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestResumeSessionReceiver.register(context); 89ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mKeyguardMonitor = keyguardMonitor; 9000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUserManager = UserManager.get(context); 9100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos IntentFilter filter = new IntentFilter(); 9200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_ADDED); 9300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_REMOVED); 9400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_INFO_CHANGED); 9500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 96e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos filter.addAction(Intent.ACTION_USER_STOPPING); 97f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov filter.addAction(ACTION_REMOVE_GUEST); 987cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, 99e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos null /* permission */, null /* scheduler */); 1002daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 101ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1022daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mContext.getContentResolver().registerContentObserver( 1032daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, 104ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 105ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mContext.getContentResolver().registerContentObserver( 106ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true, 107ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver); 108ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Fetch initial values. 109ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mSettingsObserver.onChange(false); 110ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 111ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos keyguardMonitor.addCallback(mCallback); 1122daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 113e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(UserHandle.USER_NULL); 11400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 11500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 116e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos /** 117e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * Refreshes users from UserManager. 118e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 119e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * The pictures are only loaded if they have not been loaded yet. 120e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * 121e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos * @param forcePictureLoadForId forces the picture of the given user to be reloaded. 122e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos */ 12395ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani @SuppressWarnings("unchecked") 124e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void refreshUsers(int forcePictureLoadForId) { 125c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos 126c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); 127c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos final int N = mUsers.size(); 128c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos for (int i = 0; i < N; i++) { 129c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos UserRecord r = mUsers.get(i); 130c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos if (r == null || r.info == null 131c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos || r.info.id == forcePictureLoadForId || r.picture == null) { 132c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos continue; 133e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 134c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos bitmaps.put(r.info.id, r.picture); 135e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 136e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 137ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final boolean addUsersWhenLocked = mAddUsersWhenLocked; 138e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { 139e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos @SuppressWarnings("unchecked") 14000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 141e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { 142e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos final SparseArray<Bitmap> bitmaps = params[0]; 14300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos List<UserInfo> infos = mUserManager.getUsers(true); 14400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (infos == null) { 14500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 14600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 14700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ArrayList<UserRecord> records = new ArrayList<>(infos.size()); 14800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int currentId = ActivityManager.getCurrentUser(); 1497cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserInfo currentUserInfo = null; 15000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord guestRecord = null; 1514d75c079f35d85b687d8349e5e2940447d01198eDan Sandler int avatarSize = mContext.getResources() 1524d75c079f35d85b687d8349e5e2940447d01198eDan Sandler .getDimensionPixelSize(R.dimen.max_avatar_size); 15300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 15400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (UserInfo info : infos) { 15500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean isCurrent = currentId == info.id; 1567cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (isCurrent) { 1577cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen currentUserInfo = info; 1587cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } 15900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info.isGuest()) { 16000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos guestRecord = new UserRecord(info, null /* picture */, 161ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, isCurrent, false /* isAddUser */, 162ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isRestricted */); 1637cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen } else if (info.supportsSwitchToByUser()) { 164c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos Bitmap picture = bitmaps.get(info.id); 165c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos if (picture == null) { 166c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos picture = mUserManager.getUserIcon(info.id); 167cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos 168c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos if (picture != null) { 169cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos picture = BitmapHelper.createCircularClip( 170c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos picture, avatarSize, avatarSize); 171cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos } 1724d75c079f35d85b687d8349e5e2940447d01198eDan Sandler } 173bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = isCurrent ? 0 : records.size(); 174bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, new UserRecord(info, picture, false /* isGuest */, 175bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos isCurrent, false /* isAddUser */, false /* isRestricted */)); 17600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 17700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 17800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 1797cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean systemCanCreateUsers = !mUserManager.hasUserRestriction( 1807cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM); 1817cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean currentUserCanCreateUsers = currentUserInfo != null 1827cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && (currentUserInfo.isAdmin() 1837cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen || currentUserInfo.id == UserHandle.USER_SYSTEM) 1847cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen && systemCanCreateUsers; 1857cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked; 186ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) 187ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos && guestRecord == null; 188ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) 18995ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani && mUserManager.canAddMoreUsers(); 190ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean createIsRestricted = !addUsersWhenLocked; 191ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 1922daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (!mSimpleUserSwitcher) { 1932daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk if (guestRecord == null) { 194ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (canCreateGuest) { 195ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos records.add(new UserRecord(null /* info */, null /* picture */, 196ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos true /* isGuest */, false /* isCurrent */, 197ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isAddUser */, createIsRestricted)); 198ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 1992daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } else { 200bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos int index = guestRecord.isCurrent ? 0 : records.size(); 201bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos records.add(index, guestRecord); 2022daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 20300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 20400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 205092be7de024b8b1a050ad247a016febc795546afJason Monk if (!mSimpleUserSwitcher && canCreateUser) { 206ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos records.add(new UserRecord(null /* info */, null /* picture */, 207ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos false /* isGuest */, false /* isCurrent */, true /* isAddUser */, 208ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos createIsRestricted)); 209ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 210ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 21100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return records; 21200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 21300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 21400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 21500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected void onPostExecute(ArrayList<UserRecord> userRecords) { 21600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (userRecords != null) { 21700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers = userRecords; 21800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 21900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 22000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 221ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }.execute((SparseArray) bitmaps); 22200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 22300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 22400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private void notifyAdapters() { 22500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = mAdapters.size() - 1; i >= 0; i--) { 22600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos BaseUserAdapter adapter = mAdapters.get(i).get(); 22700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (adapter != null) { 22800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos adapter.notifyDataSetChanged(); 22900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 23000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mAdapters.remove(i); 23100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 23400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 2352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public boolean isSimpleUserSwitcher() { 2362daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk return mSimpleUserSwitcher; 2372daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk } 2382daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 23900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 24000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos int id; 24100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isGuest && record.info == null) { 24200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos // No guest user. Create one. 243f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos UserInfo guest = mUserManager.createGuest( 244f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext, mContext.getString(R.string.guest_nickname)); 245f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (guest == null) { 246f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create guest, most likely because there already exists one, we just 247f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // haven't reloaded the user list yet. 248f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 249f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 250f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos id = guest.id; 251ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (record.isAddUser) { 2520c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos showAddUserDialog(); 2530c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos return; 25400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 25500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos id = record.info.id; 25600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 25700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 25800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (ActivityManager.getCurrentUser() == id) { 259e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.isGuest) { 2605005244f10442e75c1f48973fdddce5facf3f360Adrian Roos showExitGuestDialog(id); 261e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 26200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return; 26300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 26400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 265e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos switchToUserId(id); 266e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 267e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 268e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void switchToUserId(int id) { 26900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos try { 27000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos ActivityManagerNative.getDefault().switchUser(id); 27100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } catch (RemoteException e) { 27200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos Log.e(TAG, "Couldn't switch user.", e); 27300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 27500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 2765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private void showExitGuestDialog(int id) { 2775005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 2785005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 2795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 2805005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = new ExitGuestDialog(mContext, id); 2815005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.show(); 2825005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 2835005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 2840c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private void showAddUserDialog() { 2850c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (mAddUserDialog != null && mAddUserDialog.isShowing()) { 2860c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.cancel(); 2870c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 2880c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog = new AddUserDialog(mContext); 2890c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos mAddUserDialog.show(); 2900c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 2910c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 292e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos private void exitGuest(int id) { 2937cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen int newId = UserHandle.USER_SYSTEM; 2947cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (mLastNonGuestUser != UserHandle.USER_SYSTEM) { 29570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser); 2967cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) { 29770441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos newId = info.id; 29870441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 29970441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 30070441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos switchToUserId(newId); 301e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos mUserManager.removeUser(id); 302e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 303e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 30400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private BroadcastReceiver mReceiver = new BroadcastReceiver() { 30500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 30600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void onReceive(Context context, Intent intent) { 3075005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (DEBUG) { 3085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos Log.v(TAG, "Broadcast: a=" + intent.getAction() 3095005244f10442e75c1f48973fdddce5facf3f360Adrian Roos + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); 3105005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 311f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { 312f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov int currentUser = ActivityManager.getCurrentUser(); 313f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentUser); 314f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 315f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showExitGuestDialog(currentUser); 316f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 317f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov return; 318f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 319f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) { 320f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 321f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov UserInfo userInfo = mUserManager.getUserInfo(currentId); 322f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov if (userInfo != null && userInfo.isGuest()) { 323f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov showGuestNotification(currentId); 324f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 325f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 326f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 32700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 3285005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { 3295005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog.cancel(); 3305005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mExitGuestDialog = null; 3315005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 3325005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 33300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 3347cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen final UserInfo userInfo = mUserManager.getUserInfo(currentId); 33500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final int N = mUsers.size(); 33600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < N; i++) { 33700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos UserRecord record = mUsers.get(i); 338e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (record.info == null) continue; 33900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos boolean shouldBeCurrent = record.info.id == currentId; 34000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (record.isCurrent != shouldBeCurrent) { 34100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent)); 34200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 34370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos if (shouldBeCurrent && !record.isGuest) { 34470441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos mLastNonGuestUser = record.info.id; 34570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos } 3467cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) { 347ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // Immediately remove restricted records in case the AsyncTask is too slow. 348ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mUsers.remove(i); 349ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos i--; 350ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 35100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 35200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos notifyAdapters(); 35300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 354e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos int forcePictureLoadForId = UserHandle.USER_NULL; 355e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { 356e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 357e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos UserHandle.USER_NULL); 358e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 359e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos refreshUsers(forcePictureLoadForId); 36000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 361f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov 362f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov private void showGuestNotification(int guestUserId) { 363f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov PendingIntent removeGuestPI = PendingIntent.getBroadcastAsUser(mContext, 3647cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM); 365f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov Notification notification = new Notification.Builder(mContext) 366f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setVisibility(Notification.VISIBILITY_SECRET) 367f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setPriority(Notification.PRIORITY_MIN) 368f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setSmallIcon(R.drawable.ic_person) 369f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setContentTitle(mContext.getString(R.string.guest_notification_title)) 370f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setContentText(mContext.getString(R.string.guest_notification_text)) 371f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .setShowWhen(false) 372f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .addAction(R.drawable.ic_delete, 373f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov mContext.getString(R.string.guest_notification_remove_action), 374f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov removeGuestPI) 375f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov .build(); 376f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov NotificationManager.from(mContext).notifyAsUser(null, 0, notification, 377f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov new UserHandle(guestUserId)); 378f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov } 37900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 38000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 381ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { 3822daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk public void onChange(boolean selfChange) { 3832daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(), 3842daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0; 385ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(), 386ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0; 3872daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk refreshUsers(UserHandle.USER_NULL); 3882daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 3892daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk }; 3902daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk 39100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 39200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.println("UserSwitcherController state:"); 39370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos pw.println(" mLastNonGuestUser=" + mLastNonGuestUser); 39400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" mUsers.size="); pw.println(mUsers.size()); 39500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos for (int i = 0; i < mUsers.size(); i++) { 39600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserRecord u = mUsers.get(i); 39700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos pw.print(" "); pw.println(u.toString()); 39800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 39900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 40000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 40157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos public String getCurrentUserName(Context context) { 40257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (mUsers.isEmpty()) return null; 40357cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos UserRecord item = mUsers.get(0); 40457cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item == null || item.info == null) return null; 40557cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos if (item.isGuest) return context.getString(R.string.guest_nickname); 40657cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos return item.info.name; 40757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos } 40857cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos 40900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static abstract class BaseUserAdapter extends BaseAdapter { 41000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 41100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos final UserSwitcherController mController; 41200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 41300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos protected BaseUserAdapter(UserSwitcherController controller) { 41400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController = controller; 41500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos controller.mAdapters.add(new WeakReference<>(this)); 41600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 41700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 41800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 41900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getCount() { 420ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing() 4218a3a964d0ad13374a4c4ee8a8a1b12aa00e577f0Jason Monk && mController.mKeyguardMonitor.isSecure() 4228a3a964d0ad13374a4c4ee8a8a1b12aa00e577f0Jason Monk && !mController.mKeyguardMonitor.isTrusted(); 423ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (!secureKeyguardShowing) { 424ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return mController.mUsers.size(); 425ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 426ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos // The lock screen is secure and showing. Filter out restricted records. 427ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos final int N = mController.mUsers.size(); 428ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos int count = 0; 429ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos for (int i = 0; i < N; i++) { 430ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (mController.mUsers.get(i).isRestricted) { 431ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos break; 432ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else { 433ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos count++; 434ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 435ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 436ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return count; 43700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 43800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 43900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 44000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord getItem(int position) { 44100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return mController.mUsers.get(position); 44200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 44300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 44400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 44500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public long getItemId(int position) { 446e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return position; 44700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 44800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 44900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void switchTo(UserRecord record) { 45000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos mController.switchTo(record); 45100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 452e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos 453e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos public String getName(Context context, UserRecord item) { 454e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isGuest) { 455e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos if (item.isCurrent) { 456e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString(R.string.guest_exit_guest); 457e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 458e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return context.getString( 459e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos item.info == null ? R.string.guest_new_guest : R.string.guest_nickname); 460e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 461ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (item.isAddUser) { 462ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getString(R.string.user_add_user); 463e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } else { 464e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos return item.info.name; 465e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 466e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos } 467723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos 468ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public Drawable getDrawable(Context context, UserRecord item) { 469ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (item.isAddUser) { 470ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return context.getDrawable(R.drawable.ic_add_circle_qs); 471ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 47264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina return UserIcons.getDefaultUserIcon(item.isGuest ? UserHandle.USER_NULL : item.info.id, 47364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina /* light= */ true); 474ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 475844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos 476844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos public void refresh() { 477844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos mController.refreshUsers(UserHandle.USER_NULL); 478844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos } 47900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 48000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 48100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public static final class UserRecord { 48200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final UserInfo info; 48300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final Bitmap picture; 48400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isGuest; 48500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final boolean isCurrent; 486ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isAddUser; 487ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos /** If true, the record is only visible to the owner and only when unlocked. */ 488ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public final boolean isRestricted; 48900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 490ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent, 491ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos boolean isAddUser, boolean isRestricted) { 49200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.info = info; 49300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.picture = picture; 49400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isGuest = isGuest; 49500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos this.isCurrent = isCurrent; 496ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isAddUser = isAddUser; 497ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos this.isRestricted = isRestricted; 49800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 49900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 50000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public UserRecord copyWithIsCurrent(boolean _isCurrent) { 501ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted); 50200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 50300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 50400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public String toString() { 50500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos StringBuilder sb = new StringBuilder(); 50600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("UserRecord("); 50700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (info != null) { 50800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append("name=\"" + info.name + "\" id=" + info.id); 50900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } else { 510ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) { 511ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add guest placeholder>"); 512ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } else if (isAddUser) { 513ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos sb.append("<add user placeholder>"); 514ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 51500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 516ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isGuest) sb.append(" <isGuest>"); 517ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isAddUser) sb.append(" <isAddUser>"); 518ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isCurrent) sb.append(" <isCurrent>"); 519ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (picture != null) sb.append(" <hasPicture>"); 520ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos if (isRestricted) sb.append(" <isRestricted>"); 52100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos sb.append(')'); 52200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return sb.toString(); 52300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 52400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 52500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 52600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() { 52700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos private final Intent USER_SETTINGS_INTENT = new Intent("android.settings.USER_SETTINGS"); 52800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 52900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 53000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public int getTitle() { 53100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return R.string.quick_settings_user_title; 53200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 53300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 53400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 53500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public View createDetailView(Context context, View convertView, ViewGroup parent) { 5361940892d891c1d2538f51608b6618af646ab7481Adrian Roos UserDetailView v; 53700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos if (!(convertView instanceof UserDetailView)) { 5381940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = UserDetailView.inflate(context, parent, false); 53900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos v.createAndSetAdapter(UserSwitcherController.this); 5401940892d891c1d2538f51608b6618af646ab7481Adrian Roos } else { 5411940892d891c1d2538f51608b6618af646ab7481Adrian Roos v = (UserDetailView) convertView; 54200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 543844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos v.refreshAdapter(); 54400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return v; 54500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 54600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 54700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 54800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Intent getSettingsIntent() { 54900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return USER_SETTINGS_INTENT; 55000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 55100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 55200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 55300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public Boolean getToggleState() { 55400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos return null; 55500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 55600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos 55700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos @Override 55800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos public void setToggleState(boolean state) { 55900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos } 560457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren 561457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren @Override 562457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren public int getMetricsCategory() { 563457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren return MetricsLogger.QS_USERDETAIL; 564457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren } 56500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos }; 5665005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 567ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { 568ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos @Override 569ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos public void onKeyguardChanged() { 570ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos notifyAdapters(); 571ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos } 572ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos }; 573ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos 5745005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final class ExitGuestDialog extends SystemUIDialog implements 5755005244f10442e75c1f48973fdddce5facf3f360Adrian Roos DialogInterface.OnClickListener { 5765005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 5775005244f10442e75c1f48973fdddce5facf3f360Adrian Roos private final int mGuestId; 5785005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 5795005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public ExitGuestDialog(Context context, int guestId) { 5805005244f10442e75c1f48973fdddce5facf3f360Adrian Roos super(context); 5815005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setTitle(R.string.guest_exit_guest_dialog_title); 5825005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); 5835005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 584e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(android.R.string.cancel), this); 5855005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 586e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani context.getString(R.string.guest_exit_guest_dialog_remove), this); 5875005244f10442e75c1f48973fdddce5facf3f360Adrian Roos setCanceledOnTouchOutside(false); 5885005244f10442e75c1f48973fdddce5facf3f360Adrian Roos mGuestId = guestId; 5895005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 5905005244f10442e75c1f48973fdddce5facf3f360Adrian Roos 5915005244f10442e75c1f48973fdddce5facf3f360Adrian Roos @Override 5925005244f10442e75c1f48973fdddce5facf3f360Adrian Roos public void onClick(DialogInterface dialog, int which) { 5935005244f10442e75c1f48973fdddce5facf3f360Adrian Roos if (which == BUTTON_NEGATIVE) { 5945005244f10442e75c1f48973fdddce5facf3f360Adrian Roos cancel(); 5955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } else { 5965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos dismiss(); 5975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos exitGuest(mGuestId); 5985005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 5995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 6005005244f10442e75c1f48973fdddce5facf3f360Adrian Roos } 6010c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 6020c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos private final class AddUserDialog extends SystemUIDialog implements 6030c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos DialogInterface.OnClickListener { 6040c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 6050c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public AddUserDialog(Context context) { 6060c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos super(context); 6070c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setTitle(R.string.user_add_user_title); 6080c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setMessage(context.getString(R.string.user_add_user_message_short)); 6090c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_NEGATIVE, 6100c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.cancel), this); 6110c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos setButton(DialogInterface.BUTTON_POSITIVE, 6120c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos context.getString(android.R.string.ok), this); 6130c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 6140c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos 6150c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos @Override 6160c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos public void onClick(DialogInterface dialog, int which) { 6170c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos if (which == BUTTON_NEGATIVE) { 6180c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos cancel(); 6190c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } else { 6200c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos dismiss(); 621ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu if (ActivityManager.isUserAMonkey()) { 622ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu return; 623ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu } 624cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen UserInfo user = mUserManager.createUser( 625f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos mContext.getString(R.string.user_new_user_name), 0 /* flags */); 626f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos if (user == null) { 627f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // Couldn't create user, most likely because there are too many, but we haven't 628f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos // been able to reload the list yet. 629f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos return; 630f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos } 631f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos int id = user.id; 63264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon( 63364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina id, /* light= */ false)); 63464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina mUserManager.setUserIcon(id, icon); 6350c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos switchToUserId(id); 6360c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 6370c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 6380c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos } 6392b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos 6402b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos public static boolean isUserSwitcherAvailable(UserManager um) { 6412b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos return UserManager.supportsMultipleUsers() && um.isUserSwitcherEnabled(); 6422b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos } 6432b154a9ec32915fe4a0dbc648344586fb5fa0261Adrian Roos 64400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos} 645