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