UserSwitcherController.java revision aa7f51fe8c6e54485f0b5037c17777b4695d19e0
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;
263c2c34bb039e92d68f466b7d194cbbe8241d8d60Winsonimport android.content.ComponentName;
2700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Context;
285005244f10442e75c1f48973fdddce5facf3f360Adrian Roosimport android.content.DialogInterface;
2900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.Intent;
3000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.IntentFilter;
3100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.content.pm.UserInfo;
322daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.database.ContentObserver;
3300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.graphics.Bitmap;
34ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roosimport android.graphics.drawable.Drawable;
3500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.AsyncTask;
362daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.os.Handler;
3700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.RemoteException;
38e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.os.UserHandle;
3900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.os.UserManager;
402daf62ce400fe58c7f0495dda432ba568a75f579Jason Monkimport android.provider.Settings;
41523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.PhoneStateListener;
42523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolovimport android.telephony.TelephonyManager;
4300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.util.Log;
44e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roosimport android.util.SparseArray;
4588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roosimport android.util.SparseBooleanArray;
4600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.View;
4700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.view.ViewGroup;
4800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport android.widget.BaseAdapter;
4900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
50f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent;
5164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.internal.util.UserIcons;
521c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils;
5364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.GuestResumeSessionReceiver;
5464d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.R;
553c2c34bb039e92d68f466b7d194cbbe8241d8d60Winsonimport com.android.systemui.SystemUISecondaryUserService;
5664d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.QSTile;
5764d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.qs.tiles.UserDetailView;
581c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport com.android.systemui.statusbar.phone.ActivityStarter;
5964d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghinaimport com.android.systemui.statusbar.phone.SystemUIDialog;
6064d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina
6100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.FileDescriptor;
6200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.io.PrintWriter;
6300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.lang.ref.WeakReference;
6400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.ArrayList;
6500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roosimport java.util.List;
6600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
671c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
681c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka
6900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos/**
7000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos * Keeps a list of all users on the device for user switching.
7100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos */
7200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roospublic class UserSwitcherController {
7300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
7400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private static final String TAG = "UserSwitcherController";
755005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    private static final boolean DEBUG = false;
762daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk    private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING =
772daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk            "lockscreenSimpleUserSwitcher";
78f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov    private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST";
79860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen    private static final String ACTION_LOGOUT_USER = "com.android.systemui.LOGOUT_USER";
8088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000;
8100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
82d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani    private static final int ID_REMOVE_GUEST = 1010;
83860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen    private static final int ID_LOGOUT_USER = 1011;
84d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani    private static final String TAG_REMOVE_GUEST = "remove_guest";
85860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen    private static final String TAG_LOGOUT_USER = "logout_user";
86860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen
87d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
88d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani
8900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private final Context mContext;
9000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private final UserManager mUserManager;
9100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
925005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    private final GuestResumeSessionReceiver mGuestResumeSessionReceiver
935005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            = new GuestResumeSessionReceiver();
94ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    private final KeyguardMonitor mKeyguardMonitor;
9588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private final Handler mHandler;
961c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka    private final ActivityStarter mActivityStarter;
9700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
9800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private ArrayList<UserRecord> mUsers = new ArrayList<>();
995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    private Dialog mExitGuestDialog;
1000c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos    private Dialog mAddUserDialog;
1017cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen    private int mLastNonGuestUser = UserHandle.USER_SYSTEM;
102ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    private boolean mSimpleUserSwitcher;
103ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    private boolean mAddUsersWhenLocked;
10488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private boolean mPauseRefreshUsers;
1053c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson    private int mSecondaryUser = UserHandle.USER_NULL;
1063c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson    private Intent mSecondaryUserServiceIntent;
10788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
10800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
10988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
1101c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            Handler handler, ActivityStarter activityStarter) {
11100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        mContext = context;
1125005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        mGuestResumeSessionReceiver.register(context);
113ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        mKeyguardMonitor = keyguardMonitor;
11488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        mHandler = handler;
1151c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        mActivityStarter = activityStarter;
11600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        mUserManager = UserManager.get(context);
11700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        IntentFilter filter = new IntentFilter();
11800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        filter.addAction(Intent.ACTION_USER_ADDED);
11900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        filter.addAction(Intent.ACTION_USER_REMOVED);
12000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
12100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        filter.addAction(Intent.ACTION_USER_SWITCHED);
122e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        filter.addAction(Intent.ACTION_USER_STOPPING);
12307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov        filter.addAction(Intent.ACTION_USER_UNLOCKED);
1247cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen        mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
125e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                null /* permission */, null /* scheduler */);
1262daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk
1273c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson        mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class);
1283c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson
129d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani        filter = new IntentFilter();
130d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani        filter.addAction(ACTION_REMOVE_GUEST);
131860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen        filter.addAction(ACTION_LOGOUT_USER);
1325891a346abbde5bfe95a52633d05533406cc6a2eAmith Yamasani        mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
133d81f8270bec71ec9a569c8308c42cacd7aba0d23Amith Yamasani                PERMISSION_SELF, null /* scheduler */);
134ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos
1352daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk        mContext.getContentResolver().registerContentObserver(
1362daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
137ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                mSettingsObserver);
138ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        mContext.getContentResolver().registerContentObserver(
139ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true,
140ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                mSettingsObserver);
14107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov        mContext.getContentResolver().registerContentObserver(
14207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                Settings.Global.getUriFor(
14307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                        Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED),
14407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                true, mSettingsObserver);
145ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        // Fetch initial values.
146ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        mSettingsObserver.onChange(false);
147ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos
148ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        keyguardMonitor.addCallback(mCallback);
149523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        listenForCallState();
1502daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk
151e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        refreshUsers(UserHandle.USER_NULL);
15200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
15300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
154e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    /**
155e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     * Refreshes users from UserManager.
156e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     *
157e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     * The pictures are only loaded if they have not been loaded yet.
158e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     *
159e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     * @param forcePictureLoadForId forces the picture of the given user to be reloaded.
160e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos     */
16195ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani    @SuppressWarnings("unchecked")
162e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    private void refreshUsers(int forcePictureLoadForId) {
16388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")");
16488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        if (forcePictureLoadForId != UserHandle.USER_NULL) {
16588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            mForcePictureLoadForUserId.put(forcePictureLoadForId, true);
16688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        }
16788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos
16888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        if (mPauseRefreshUsers) {
16988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            return;
17088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        }
171c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos
172c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos        SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size());
173c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos        final int N = mUsers.size();
174c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos        for (int i = 0; i < N; i++) {
175c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos            UserRecord r = mUsers.get(i);
17688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            if (r == null || r.picture == null ||
17788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos                    r.info == null || mForcePictureLoadForUserId.get(r.info.id)) {
178c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos                continue;
179e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            }
180c5db390f5b5c6c685267dd22cf3b2926f54fba35Adrian Roos            bitmaps.put(r.info.id, r.picture);
181e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        }
18288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        mForcePictureLoadForUserId.clear();
183e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos
184ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        final boolean addUsersWhenLocked = mAddUsersWhenLocked;
185e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() {
186e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            @SuppressWarnings("unchecked")
18700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            @Override
188e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) {
189e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                final SparseArray<Bitmap> bitmaps = params[0];
19000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                List<UserInfo> infos = mUserManager.getUsers(true);
19100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                if (infos == null) {
19200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    return null;
19300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                }
19400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                ArrayList<UserRecord> records = new ArrayList<>(infos.size());
19500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                int currentId = ActivityManager.getCurrentUser();
196523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                boolean canSwitchUsers = mUserManager.canSwitchUsers();
1977cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                UserInfo currentUserInfo = null;
19800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                UserRecord guestRecord = null;
19900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
20000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                for (UserInfo info : infos) {
20100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    boolean isCurrent = currentId == info.id;
2027cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                    if (isCurrent) {
2037cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                        currentUserInfo = info;
2047cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                    }
205523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                    boolean switchToEnabled = canSwitchUsers || isCurrent;
2061ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                    if (info.isEnabled()) {
2071ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                        if (info.isGuest()) {
208523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                            // Tapping guest icon triggers remove and a user switch therefore
209523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                            // the icon shouldn't be enabled even if the user is current
2101ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                            guestRecord = new UserRecord(info, null /* picture */,
2111ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                    true /* isGuest */, isCurrent, false /* isAddUser */,
212523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                                    false /* isRestricted */, canSwitchUsers);
2131ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                        } else if (info.supportsSwitchToByUser()) {
2141ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                            Bitmap picture = bitmaps.get(info.id);
2151ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                            if (picture == null) {
2161ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                picture = mUserManager.getUserIcon(info.id);
2171ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova
2181ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                if (picture != null) {
219aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky                                    int avatarSize = mContext.getResources()
220aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky                                            .getDimensionPixelSize(R.dimen.max_avatar_size);
221aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky                                    picture = Bitmap.createScaledBitmap(
222aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky                                            picture, avatarSize, avatarSize, true);
2231ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                }
224cba0faadbe1c8cf7c6b264b761d747f7381a2f93Adrian Roos                            }
2251ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                            int index = isCurrent ? 0 : records.size();
2261ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                            records.add(index, new UserRecord(info, picture, false /* isGuest */,
2271ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                    isCurrent, false /* isAddUser */, false /* isRestricted */,
2281ddda4793c26fd249590fd3549cf060ecb7c157bLenka Trochtova                                    switchToEnabled));
2294d75c079f35d85b687d8349e5e2940447d01198eDan Sandler                        }
23000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    }
23100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                }
23200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
233a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                boolean systemCanCreateUsers = !mUserManager.hasBaseUserRestriction(
234a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                                UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
2357cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                boolean currentUserCanCreateUsers = currentUserInfo != null
2367cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                        && (currentUserInfo.isAdmin()
237a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                                || currentUserInfo.id == UserHandle.USER_SYSTEM)
238a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                        && systemCanCreateUsers;
239a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
240a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
241ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        && guestRecord == null;
242a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
24395ab7849444125387dc88088bb5197ee463d8c17Amith Yamasani                        && mUserManager.canAddMoreUsers();
244ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                boolean createIsRestricted = !addUsersWhenLocked;
245ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos
2462daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                if (!mSimpleUserSwitcher) {
2472daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                    if (guestRecord == null) {
248ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        if (canCreateGuest) {
2491c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka                            guestRecord = new UserRecord(null /* info */, null /* picture */,
250ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                                    true /* isGuest */, false /* isCurrent */,
251523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                                    false /* isAddUser */, createIsRestricted, canSwitchUsers);
252a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                            checkIfAddUserDisallowedByAdminOnly(guestRecord);
2531c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka                            records.add(guestRecord);
254ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        }
2552daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                    } else {
256bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos                        int index = guestRecord.isCurrent ? 0 : records.size();
257bed6e3bedc8845e8f9cd59ad436d140b0875cb6bAdrian Roos                        records.add(index, guestRecord);
2582daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                    }
25900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                }
26000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
261092be7de024b8b1a050ad247a016febc795546afJason Monk                if (!mSimpleUserSwitcher && canCreateUser) {
2621c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka                    UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
263ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                            false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
264523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                            createIsRestricted, canSwitchUsers);
265a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka                    checkIfAddUserDisallowedByAdminOnly(addUserRecord);
2661c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka                    records.add(addUserRecord);
267ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                }
268ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos
26900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                return records;
27000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            }
27100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
27200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            @Override
27300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            protected void onPostExecute(ArrayList<UserRecord> userRecords) {
27400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                if (userRecords != null) {
27500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    mUsers = userRecords;
27600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    notifyAdapters();
27700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                }
27800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            }
279ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        }.execute((SparseArray) bitmaps);
28000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
28100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
28288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private void pauseRefreshUsers() {
28388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        if (!mPauseRefreshUsers) {
28488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS);
28588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            mPauseRefreshUsers = true;
28688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        }
28788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    }
28888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos
28900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private void notifyAdapters() {
29000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        for (int i = mAdapters.size() - 1; i >= 0; i--) {
29100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            BaseUserAdapter adapter = mAdapters.get(i).get();
29200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            if (adapter != null) {
29300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                adapter.notifyDataSetChanged();
29400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            } else {
29500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                mAdapters.remove(i);
29600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            }
29700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
29800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
29900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
3002daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk    public boolean isSimpleUserSwitcher() {
3012daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk        return mSimpleUserSwitcher;
3022daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk    }
3032daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk
304cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia    public boolean useFullscreenUserSwitcher() {
305cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        // Use adb to override:
306cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        // adb shell settings put system enable_fullscreen_user_switcher 0  # Turn it off.
307cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        // adb shell settings put system enable_fullscreen_user_switcher 1  # Turn it on.
308cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        // Restart SystemUI or adb reboot.
309cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        final int DEFAULT = -1;
310cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        final int overrideUseFullscreenUserSwitcher =
311cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia                Settings.System.getInt(mContext.getContentResolver(),
312cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia                        "enable_fullscreen_user_switcher", DEFAULT);
313cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        if (overrideUseFullscreenUserSwitcher != DEFAULT) {
314cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia            return overrideUseFullscreenUserSwitcher != 0;
315cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        }
316cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        // Otherwise default to the build setting.
31740f9dabaa880eaff54099a3763224b241a6668e6Xiyuan Xia        return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher);
318cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia    }
319cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia
3201b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia    public void logoutCurrentUser() {
3211b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia        int currentUser = ActivityManager.getCurrentUser();
3221b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia        if (currentUser != UserHandle.USER_SYSTEM) {
323b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov            pauseRefreshUsers();
324b5690bc3086af1d1f064a080c728090de24d6f96Fyodor Kupolov            ActivityManager.logoutCurrentUser();
3251b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia        }
3261b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia    }
3271b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia
328cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia    public void removeUserId(int userId) {
329cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        if (userId == UserHandle.USER_SYSTEM) {
330cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia            Log.w(TAG, "User " + userId + " could not removed.");
331cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia            return;
332cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        }
333cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        if (ActivityManager.getCurrentUser() == userId) {
334cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia            switchToUserId(UserHandle.USER_SYSTEM);
335cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        }
336cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        if (mUserManager.removeUser(userId)) {
337cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia            refreshUsers(UserHandle.USER_NULL);
338cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia        }
339cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia    }
340cc3a74f6ef13ca9a783845e7a04ca6561035c98bXiyuan Xia
34100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    public void switchTo(UserRecord record) {
34200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        int id;
34300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        if (record.isGuest && record.info == null) {
34400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            // No guest user. Create one.
345f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos            UserInfo guest = mUserManager.createGuest(
346f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                    mContext, mContext.getString(R.string.guest_nickname));
347f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos            if (guest == null) {
348f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                // Couldn't create guest, most likely because there already exists one, we just
349f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                // haven't reloaded the user list yet.
350f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                return;
351f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos            }
352f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos            id = guest.id;
353ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        } else if (record.isAddUser) {
3540c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            showAddUserDialog();
3550c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            return;
35600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        } else {
35700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            id = record.info.id;
35800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
35900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
36000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        if (ActivityManager.getCurrentUser() == id) {
361e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            if (record.isGuest) {
3625005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                showExitGuestDialog(id);
363e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            }
36400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return;
36500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
36600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
367e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        switchToUserId(id);
368e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    }
369e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos
370caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov    public void switchTo(int userId) {
371caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov        final int count = mUsers.size();
372caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov        for (int i = 0; i < count; ++i) {
373caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov            UserRecord record = mUsers.get(i);
374caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov            if (record.info != null && record.info.id == userId) {
375caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov                switchTo(record);
376caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov                return;
377caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov            }
378caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov        }
379caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov
380caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov        Log.e(TAG, "Couldn't switch to user, id=" + userId);
381caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov    }
382caab2666bd8dbf1e499c309a62f4dff0056d2948Fyodor Kupolov
383e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    private void switchToUserId(int id) {
38400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        try {
38588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            pauseRefreshUsers();
38600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            ActivityManagerNative.getDefault().switchUser(id);
38700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        } catch (RemoteException e) {
38800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            Log.e(TAG, "Couldn't switch user.", e);
38900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
39000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
39100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
3925005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    private void showExitGuestDialog(int id) {
3935005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
3945005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            mExitGuestDialog.cancel();
3955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        }
3965005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        mExitGuestDialog = new ExitGuestDialog(mContext, id);
3975005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        mExitGuestDialog.show();
3985005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    }
3995005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
4000c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos    private void showAddUserDialog() {
4010c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        if (mAddUserDialog != null && mAddUserDialog.isShowing()) {
4020c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            mAddUserDialog.cancel();
4030c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        }
4040c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        mAddUserDialog = new AddUserDialog(mContext);
4050c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        mAddUserDialog.show();
4060c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos    }
4070c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos
408e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    private void exitGuest(int id) {
4097cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen        int newId = UserHandle.USER_SYSTEM;
4107cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen        if (mLastNonGuestUser != UserHandle.USER_SYSTEM) {
41170441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos            UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
4127cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen            if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
41370441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos                newId = info.id;
41470441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos            }
41570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos        }
41670441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos        switchToUserId(newId);
417e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        mUserManager.removeUser(id);
418e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos    }
419e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos
420523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov    private void listenForCallState() {
421523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        TelephonyManager.from(mContext).listen(new PhoneStateListener() {
422523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov            private int mCallState;
423523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov            @Override
424523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov            public void onCallStateChanged(int state, String incomingNumber) {
425523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                if (mCallState == state) return;
426523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                if (DEBUG) Log.v(TAG, "Call state changed: " + state);
427523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                mCallState = state;
428523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                int currentUserId = ActivityManager.getCurrentUser();
429523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                UserInfo userInfo = mUserManager.getUserInfo(currentUserId);
430523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                if (userInfo != null && userInfo.isGuest()) {
431523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                    showGuestNotification(currentUserId);
432523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                }
433523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                refreshUsers(UserHandle.USER_NULL);
434523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov            }
435523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        }, PhoneStateListener.LISTEN_CALL_STATE);
436523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov    }
437523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov
43800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
43900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
44000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public void onReceive(Context context, Intent intent) {
4415005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            if (DEBUG) {
4425005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                Log.v(TAG, "Broadcast: a=" + intent.getAction()
4435005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                       + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1));
4445005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            }
44588b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos
44688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            boolean unpauseRefreshUsers = false;
44788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            int forcePictureLoadForId = UserHandle.USER_NULL;
44888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos
449f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov            if (ACTION_REMOVE_GUEST.equals(intent.getAction())) {
450f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                int currentUser = ActivityManager.getCurrentUser();
451f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                UserInfo userInfo = mUserManager.getUserInfo(currentUser);
452f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                if (userInfo != null && userInfo.isGuest()) {
453f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                    showExitGuestDialog(currentUser);
454f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                }
455f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov                return;
45680996bbf40ff192117c391074ed2f9b2cde4e69aAdrian Roos            } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) {
4571b30f79cffbe9e0c2b974fa3ee48001edcdd6c05Xiyuan Xia                logoutCurrentUser();
45888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
4595005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
4605005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                    mExitGuestDialog.cancel();
4615005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                    mExitGuestDialog = null;
4625005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                }
4635005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
46400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
4657cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                final UserInfo userInfo = mUserManager.getUserInfo(currentId);
46600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                final int N = mUsers.size();
46700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                for (int i = 0; i < N; i++) {
46800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    UserRecord record = mUsers.get(i);
469e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                    if (record.info == null) continue;
47000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    boolean shouldBeCurrent = record.info.id == currentId;
47100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    if (record.isCurrent != shouldBeCurrent) {
47200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                        mUsers.set(i, record.copyWithIsCurrent(shouldBeCurrent));
47300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                    }
47470441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos                    if (shouldBeCurrent && !record.isGuest) {
47570441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos                        mLastNonGuestUser = record.info.id;
47670441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos                    }
4777cb69df507f5f7956c52a2868a0d6e89aec6dde2Xiaohui Chen                    if ((userInfo == null || !userInfo.isAdmin()) && record.isRestricted) {
478ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        // Immediately remove restricted records in case the AsyncTask is too slow.
479ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        mUsers.remove(i);
480ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                        i--;
481ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    }
48200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                }
48300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                notifyAdapters();
484860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen
4853c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                // Disconnect from the old secondary user's service
4863c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                if (mSecondaryUser != UserHandle.USER_NULL) {
4873c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                    context.stopServiceAsUser(mSecondaryUserServiceIntent,
4883c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                            UserHandle.of(mSecondaryUser));
4893c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                    mSecondaryUser = UserHandle.USER_NULL;
4903c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                }
4913c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                // Connect to the new secondary user's service (purely to ensure that a persistent
4923c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                // SystemUI application is created for that user)
4933c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                if (userInfo != null && !userInfo.isPrimary()) {
4943c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                    context.startServiceAsUser(mSecondaryUserServiceIntent,
4953c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                            UserHandle.of(userInfo.id));
4963c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                    mSecondaryUser = userInfo.id;
4973c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson                }
4983c2c34bb039e92d68f466b7d194cbbe8241d8d60Winson
499860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest()
500860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                        && userInfo.id != UserHandle.USER_SYSTEM) {
501860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    showLogoutNotification(currentId);
502860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                }
503ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov                if (userInfo != null && userInfo.isGuest()) {
504ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov                    showGuestNotification(currentId);
505ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov                }
50688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos                unpauseRefreshUsers = true;
50788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) {
508e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
509e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                        UserHandle.USER_NULL);
51007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov            } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
51107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                // Unlocking the system user may require a refresh
51207140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
51307140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                if (userId != UserHandle.USER_SYSTEM) {
51407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                    return;
51507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                }
516e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            }
517e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            refreshUsers(forcePictureLoadForId);
51888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            if (unpauseRefreshUsers) {
51988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos                mUnpauseRefreshUsers.run();
52088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            }
52100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
522f4d6ad26636760163083ae84c40d5b19cb6650f6Fyodor Kupolov
523860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen        private void showLogoutNotification(int userId) {
524860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen            PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext,
525860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM);
526860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen            Notification notification = new Notification.Builder(mContext)
527860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setVisibility(Notification.VISIBILITY_SECRET)
528860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setPriority(Notification.PRIORITY_MIN)
529860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setSmallIcon(R.drawable.ic_person)
530860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setContentTitle(mContext.getString(R.string.user_logout_notification_title))
531860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setContentText(mContext.getString(R.string.user_logout_notification_text))
53252408f4fb5dab950847aa12e3bea44399ccd0d6eFyodor Kupolov                    .setContentIntent(logoutPI)
533ce161861c3507c91c25b2491abac1e7611d14c5cFyodor Kupolov                    .setOngoing(true)
534860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .setShowWhen(false)
535860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .addAction(R.drawable.ic_delete,
536860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                            mContext.getString(R.string.user_logout_notification_action),
537860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                            logoutPI)
538860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    .build();
539860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen            NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER, ID_LOGOUT_USER,
540860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen                    notification, new UserHandle(userId));
541860397f6521249f1e2733e65ccebe0c0e781b82aXiaohui Chen        }
54200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    };
54300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
544523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov    private void showGuestNotification(int guestUserId) {
545523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        boolean canSwitchUsers = mUserManager.canSwitchUsers();
546523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        // Disable 'Remove guest' action if cannot switch users right now
547523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext,
548523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null;
549523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov
550523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        Notification notification = new Notification.Builder(mContext)
551523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setVisibility(Notification.VISIBILITY_SECRET)
552523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setPriority(Notification.PRIORITY_MIN)
553523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setSmallIcon(R.drawable.ic_person)
554523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setContentTitle(mContext.getString(R.string.guest_notification_title))
555523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setContentText(mContext.getString(R.string.guest_notification_text))
556523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setContentIntent(removeGuestPI)
557523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .setShowWhen(false)
558523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .addAction(R.drawable.ic_delete,
559523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                        mContext.getString(R.string.guest_notification_remove_action),
560523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                        removeGuestPI)
561523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                .build();
562523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov        NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, ID_REMOVE_GUEST,
563523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov                notification, new UserHandle(guestUserId));
564523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov    }
565523c404612c634f6901205fee4f4cae594f62982Fyodor Kupolov
56688b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    private final Runnable mUnpauseRefreshUsers = new Runnable() {
56788b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        @Override
56888b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        public void run() {
56988b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            mHandler.removeCallbacks(this);
57088b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            mPauseRefreshUsers = false;
57188b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos            refreshUsers(UserHandle.USER_NULL);
57288b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos        }
57388b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos    };
57488b1193ea2880683a6a3fdf9a5a397370a166680Adrian Roos
575ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
5762daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk        public void onChange(boolean selfChange) {
5772daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk            mSimpleUserSwitcher = Settings.Global.getInt(mContext.getContentResolver(),
5782daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk                    SIMPLE_USER_SWITCHER_GLOBAL_SETTING, 0) != 0;
579ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            mAddUsersWhenLocked = Settings.Global.getInt(mContext.getContentResolver(),
580ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
5812daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk            refreshUsers(UserHandle.USER_NULL);
5822daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk        };
5832daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk    };
5842daf62ce400fe58c7f0495dda432ba568a75f579Jason Monk
58500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
58600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        pw.println("UserSwitcherController state:");
58770441467f4dc232cd8e6142f0afc117787dc979bAdrian Roos        pw.println("  mLastNonGuestUser=" + mLastNonGuestUser);
58800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        pw.print("  mUsers.size="); pw.println(mUsers.size());
58900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        for (int i = 0; i < mUsers.size(); i++) {
59000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            final UserRecord u = mUsers.get(i);
59100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            pw.print("    "); pw.println(u.toString());
59200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
59300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
59400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
59557cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos    public String getCurrentUserName(Context context) {
59657cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos        if (mUsers.isEmpty()) return null;
59757cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos        UserRecord item = mUsers.get(0);
59857cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos        if (item == null || item.info == null) return null;
59957cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos        if (item.isGuest) return context.getString(R.string.guest_nickname);
60057cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos        return item.info.name;
60157cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos    }
60257cf5702e0634b8cb25daa8f2f73292428ec4e08Adrian Roos
60300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    public static abstract class BaseUserAdapter extends BaseAdapter {
60400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
60500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        final UserSwitcherController mController;
60600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
60700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        protected BaseUserAdapter(UserSwitcherController controller) {
60800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            mController = controller;
60900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            controller.mAdapters.add(new WeakReference<>(this));
61000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
61100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
61200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
61300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public int getCount() {
614ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing()
6158a3a964d0ad13374a4c4ee8a8a1b12aa00e577f0Jason Monk                    && mController.mKeyguardMonitor.isSecure()
616e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek                    && !mController.mKeyguardMonitor.canSkipBouncer();
617ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (!secureKeyguardShowing) {
618ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                return mController.mUsers.size();
619ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            }
620ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            // The lock screen is secure and showing. Filter out restricted records.
621ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            final int N = mController.mUsers.size();
622ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            int count = 0;
623ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            for (int i = 0; i < N; i++) {
624ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                if (mController.mUsers.get(i).isRestricted) {
625ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    break;
626ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                } else {
627ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    count++;
628ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                }
629ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            }
630ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            return count;
63100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
63200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
63300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
63400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public UserRecord getItem(int position) {
63500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return mController.mUsers.get(position);
63600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
63700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
63800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
63900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public long getItemId(int position) {
640e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            return position;
64100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
64200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
64300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public void switchTo(UserRecord record) {
64400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            mController.switchTo(record);
64500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
646e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos
647e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        public String getName(Context context, UserRecord item) {
648e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            if (item.isGuest) {
649e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                if (item.isCurrent) {
650e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                    return context.getString(R.string.guest_exit_guest);
651e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                } else {
652e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                    return context.getString(
653e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                            item.info == null ? R.string.guest_new_guest : R.string.guest_nickname);
654e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                }
655ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            } else if (item.isAddUser) {
656ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                return context.getString(R.string.user_add_user);
657e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            } else {
658e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos                return item.info.name;
659e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos            }
660e9c7d431da85b5bc03ecaa964d7a491b01466a99Adrian Roos        }
661723632ea1ae30b33e9c2055194a4464f00c48c61Adrian Roos
662ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        public Drawable getDrawable(Context context, UserRecord item) {
663ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (item.isAddUser) {
664ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                return context.getDrawable(R.drawable.ic_add_circle_qs);
665ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            }
666aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky            return UserIcons.getDefaultUserIcon(item.resolveId(), /* light= */ true);
667ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        }
668844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos
669844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos        public void refresh() {
670844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos            mController.refreshUsers(UserHandle.USER_NULL);
671844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos        }
67200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
67300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
674a8fbbb30eae03b9ed7a3e6ea78da13480a53b73dSudheer Shanka    private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) {
675ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
676ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka                UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser());
677ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka        if (admin != null && !RestrictedLockUtils.hasBaseUserRestriction(mContext,
678ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka                UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) {
6791c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            record.isDisabledByAdmin = true;
680ad143c09dfbae2f4bb26be8b2a9425edf0562b46Sudheer Shanka            record.enforcedAdmin = admin;
6811c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        } else {
6821c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            record.isDisabledByAdmin = false;
6831c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            record.enforcedAdmin = null;
6841c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        }
6851c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka    }
6861c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka
6871c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka    public void startActivity(Intent intent) {
6881c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        mActivityStarter.startActivity(intent, true);
6891c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka    }
6901c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka
69100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    public static final class UserRecord {
69200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public final UserInfo info;
69300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public final Bitmap picture;
69400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public final boolean isGuest;
69500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public final boolean isCurrent;
696ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        public final boolean isAddUser;
697ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        /** If true, the record is only visible to the owner and only when unlocked. */
698ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        public final boolean isRestricted;
6991c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        public boolean isDisabledByAdmin;
7001c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka        public EnforcedAdmin enforcedAdmin;
70107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov        public boolean isSwitchToEnabled;
70200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
703ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent,
70407140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                boolean isAddUser, boolean isRestricted, boolean isSwitchToEnabled) {
70500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            this.info = info;
70600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            this.picture = picture;
70700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            this.isGuest = isGuest;
70800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            this.isCurrent = isCurrent;
709ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            this.isAddUser = isAddUser;
710ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            this.isRestricted = isRestricted;
71107140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov            this.isSwitchToEnabled = isSwitchToEnabled;
71200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
71300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
71400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public UserRecord copyWithIsCurrent(boolean _isCurrent) {
71507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov            return new UserRecord(info, picture, isGuest, _isCurrent, isAddUser, isRestricted,
71607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                    isSwitchToEnabled);
71700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
71800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
719aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky        public int resolveId() {
720aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky            if (isGuest || info == null) {
721aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky                return UserHandle.USER_NULL;
722aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky            }
723aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky            return info.id;
724aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky        }
725aa7f51fe8c6e54485f0b5037c17777b4695d19e0Evan Rosky
72600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public String toString() {
72700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            StringBuilder sb = new StringBuilder();
72800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            sb.append("UserRecord(");
72900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            if (info != null) {
73007140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                sb.append("name=\"").append(info.name).append("\" id=").append(info.id);
73100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            } else {
732ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                if (isGuest) {
733ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    sb.append("<add guest placeholder>");
734ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                } else if (isAddUser) {
735ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                    sb.append("<add user placeholder>");
736ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos                }
73700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            }
738ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (isGuest) sb.append(" <isGuest>");
739ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (isAddUser) sb.append(" <isAddUser>");
740ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (isCurrent) sb.append(" <isCurrent>");
741ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (picture != null) sb.append(" <hasPicture>");
742ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            if (isRestricted) sb.append(" <isRestricted>");
7431c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            if (isDisabledByAdmin) {
7441c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka                sb.append(" <isDisabledByAdmin>");
74507140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                sb.append(" enforcedAdmin=").append(enforcedAdmin);
74607140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov            }
74707140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov            if (isSwitchToEnabled) {
74807140f7ffd56bf9d4946eba4e48b21a748125659Fyodor Kupolov                sb.append(" <isSwitchToEnabled>");
7491c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka            }
75000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            sb.append(')');
75100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return sb.toString();
75200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
75300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    }
75400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
75500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    public final QSTile.DetailAdapter userDetailAdapter = new QSTile.DetailAdapter() {
75676c67aa361f65dfb2f5e03d06cc1ccebce9cecd9Jason Monk        private final Intent USER_SETTINGS_INTENT = new Intent(Settings.ACTION_USER_SETTINGS);
75700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
75800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
759c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk        public CharSequence getTitle() {
760c06fbb12984a3d3e4c80ab9f819841acae5b0133Jason Monk            return mContext.getString(R.string.quick_settings_user_title);
76100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
76200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
76300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
76400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public View createDetailView(Context context, View convertView, ViewGroup parent) {
7651940892d891c1d2538f51608b6618af646ab7481Adrian Roos            UserDetailView v;
76600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            if (!(convertView instanceof UserDetailView)) {
7671940892d891c1d2538f51608b6618af646ab7481Adrian Roos                v = UserDetailView.inflate(context, parent, false);
76800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos                v.createAndSetAdapter(UserSwitcherController.this);
7691940892d891c1d2538f51608b6618af646ab7481Adrian Roos            } else {
7701940892d891c1d2538f51608b6618af646ab7481Adrian Roos                v = (UserDetailView) convertView;
77100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            }
772844c92b444dca7f5ef4d0943fb14e2cbeee49701Adrian Roos            v.refreshAdapter();
77300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return v;
77400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
77500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
77600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
77700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public Intent getSettingsIntent() {
77800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return USER_SETTINGS_INTENT;
77900a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
78000a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
78100a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
78200a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public Boolean getToggleState() {
78300a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos            return null;
78400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
78500a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos
78600a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        @Override
78700a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        public void setToggleState(boolean state) {
78800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos        }
789457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren
790457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren        @Override
791457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren        public int getMetricsCategory() {
792f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren            return MetricsEvent.QS_USERDETAIL;
793457a21cdeac04565a0c40ad8c43a928c1182ddd1Chris Wren        }
79400a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos    };
7955005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
796ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() {
797ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        @Override
798ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        public void onKeyguardChanged() {
799ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos            notifyAdapters();
800ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos        }
801ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos    };
802ccdff62159b41ab130a8f90d30edb9b9542d8c72Adrian Roos
8035005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    private final class ExitGuestDialog extends SystemUIDialog implements
8045005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            DialogInterface.OnClickListener {
8055005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
8065005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        private final int mGuestId;
8075005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
8085005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        public ExitGuestDialog(Context context, int guestId) {
8095005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            super(context);
8105005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            setTitle(R.string.guest_exit_guest_dialog_title);
8115005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
8125005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            setButton(DialogInterface.BUTTON_NEGATIVE,
813e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani                    context.getString(android.R.string.cancel), this);
8145005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            setButton(DialogInterface.BUTTON_POSITIVE,
815e5b274ac612400a7bc9f258d4ef3c366cfa1bc11Amith Yamasani                    context.getString(R.string.guest_exit_guest_dialog_remove), this);
8165005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            setCanceledOnTouchOutside(false);
8175005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            mGuestId = guestId;
8185005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        }
8195005244f10442e75c1f48973fdddce5facf3f360Adrian Roos
8205005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        @Override
8215005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        public void onClick(DialogInterface dialog, int which) {
8225005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            if (which == BUTTON_NEGATIVE) {
8235005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                cancel();
8245005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            } else {
8255005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                dismiss();
8265005244f10442e75c1f48973fdddce5facf3f360Adrian Roos                exitGuest(mGuestId);
8275005244f10442e75c1f48973fdddce5facf3f360Adrian Roos            }
8285005244f10442e75c1f48973fdddce5facf3f360Adrian Roos        }
8295005244f10442e75c1f48973fdddce5facf3f360Adrian Roos    }
8300c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos
8310c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos    private final class AddUserDialog extends SystemUIDialog implements
8320c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            DialogInterface.OnClickListener {
8330c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos
8340c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        public AddUserDialog(Context context) {
8350c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            super(context);
8360c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            setTitle(R.string.user_add_user_title);
8370c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            setMessage(context.getString(R.string.user_add_user_message_short));
8380c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            setButton(DialogInterface.BUTTON_NEGATIVE,
8390c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos                    context.getString(android.R.string.cancel), this);
8400c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            setButton(DialogInterface.BUTTON_POSITIVE,
8410c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos                    context.getString(android.R.string.ok), this);
8420c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        }
8430c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos
8440c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        @Override
8450c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        public void onClick(DialogInterface dialog, int which) {
8460c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            if (which == BUTTON_NEGATIVE) {
8470c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos                cancel();
8480c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            } else {
8490c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos                dismiss();
850ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu                if (ActivityManager.isUserAMonkey()) {
851ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu                    return;
852ccbeb61ac21527839deb115199cbe98fa2b73c05Guang Zhu                }
853cfe64c8afa9f30d8874c72440c3992e79fdb60c9Xiaohui Chen                UserInfo user = mUserManager.createUser(
854f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                        mContext.getString(R.string.user_new_user_name), 0 /* flags */);
855f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                if (user == null) {
856f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                    // Couldn't create user, most likely because there are too many, but we haven't
857f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                    // been able to reload the list yet.
858f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                    return;
859f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                }
860f99727cb878f9709f6c0263c0283257decbaebadAdrian Roos                int id = user.id;
86164d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina                Bitmap icon = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
86264d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina                        id, /* light= */ false));
86364d4dca63f65e4c7d4a829c85ff6670bdd34e2ebAlexandra Gherghina                mUserManager.setUserIcon(id, icon);
8640c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos                switchToUserId(id);
8650c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos            }
8660c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos        }
8670c6763a19f32f73f8a940aaee7abecb2a04d1889Adrian Roos    }
86800a0b1f397557790cf9ab55fe06e72a96ebc5353Adrian Roos}
869