Add full screen user switcher to lock screen

- Add a FULLSCREEN_USER_SWITCHER status bar state;
- Switch to this state when lock screen is shown and fullscreen
  user switcher is enabled;
- Add a build config and a test boolean system setting to enable
  fullscreen switcher;
- Placeholder GridView UI for fullscreen user switcher;

Bug:19908596
Change-Id: Ief1bc987532522245f4172beca19053d34004cee
diff --git a/packages/SystemUI/res/layout/fullscreen_user_pod.xml b/packages/SystemUI/res/layout/fullscreen_user_pod.xml
new file mode 100644
index 0000000..12f0a80
--- /dev/null
+++ b/packages/SystemUI/res/layout/fullscreen_user_pod.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--  LinearLayout -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:gravity="top|center_horizontal"
+    android:layout_width="180dp"
+    android:layout_height="wrap_content">
+
+    <ImageView android:id="@+id/user_avatar"
+               android:padding="10dp"
+               android:layout_gravity="center"
+               android:layout_width="160dp"
+               android:layout_height="160dp" />
+
+    <TextView android:id="@+id/user_name"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:textSize="@dimen/qs_detail_item_secondary_text_size"
+              android:textColor="@color/qs_user_detail_name"
+              android:gravity="center_horizontal" />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/fullscreen_user_switcher.xml
new file mode 100644
index 0000000..46c1896
--- /dev/null
+++ b/packages/SystemUI/res/layout/fullscreen_user_switcher.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:fitsSystemWindows="true"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:visibility="gone">
+    <com.android.systemui.statusbar.UserGridView
+        android:id="@+id/user_grid"
+        android:layout_gravity="center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingStart="10dp"
+        android:paddingEnd="10dp"
+        android:columnWidth="180dp"
+        android:verticalSpacing="10dp"
+        android:horizontalSpacing="10dp"
+        android:stretchMode="columnWidth"
+        android:gravity="center">
+    </com.android.systemui.statusbar.UserGridView>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index e42ce66..7ac9c41 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -79,6 +79,11 @@
         </FrameLayout>
     </FrameLayout>
 
+    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
+              android:layout="@layout/fullscreen_user_switcher"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"/>
+
     <com.android.systemui.statusbar.phone.PanelHolder
         android:id="@+id/panel_holder"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index daf42fb..66470cb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -294,5 +294,8 @@
     <!-- Whether to show a "shelf" of apps at the bottom of the screen. -->
     <bool name="config_enableAppShelf">false</bool>
 
+    <!-- Whether to show the full screen user switcher. -->
+    <bool name="enable_fullscreen_user_switcher">false</bool>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 045bc4a..918d856 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -867,6 +867,14 @@
     <!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] -->
     <string name="user_add_user_message_short" msgid="1511354412249044381">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string>
 
+    <!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
+    <string name="user_remove_user_title">Remove user?</string>
+
+    <!-- Message of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] -->
+    <string name="user_remove_user_message">All apps and data of this user will be deleted.</string>
+
+    <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
+    <string name="user_remove_user_remove">Remove</string>
 
     <!-- Battery saver notification title. [CHAR LIMIT=60]-->
     <string name="battery_saver_notification_title">Battery saver is on</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
index 9d75228..7e7fc3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
@@ -37,4 +37,8 @@
      */
     public static final int SHADE_LOCKED = 2;
 
+    /**
+     * Status bar is locked and shows the full screen user switcher.
+     */
+    public static final int FULLSCREEN_USER_SWITCHER = 3;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
new file mode 100644
index 0000000..32caf9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+
+public class UserGridView extends GridView {
+
+    private PhoneStatusBar mStatusBar;
+    private UserSwitcherController mUserSwitcherController;
+    private Adapter mAdapter;
+    private int mPendingUserId = UserHandle.USER_NULL;
+
+    public UserGridView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void init(PhoneStatusBar statusBar, UserSwitcherController userSwitcherController) {
+        mStatusBar = statusBar;
+        mUserSwitcherController = userSwitcherController;
+        mAdapter = new Adapter(mUserSwitcherController);
+        setAdapter(mAdapter);
+
+        setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                mPendingUserId = UserHandle.USER_NULL;
+                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
+                if (record == null) {
+                    return;
+                }
+
+                if (record.isGuest || record.isAddUser) {
+                    mUserSwitcherController.switchTo(record);
+                    return;
+                }
+
+                if (record.isCurrent) {
+                    showOfflineAuthUi();
+                } else {
+                    mPendingUserId = record.info.id;
+                    mUserSwitcherController.switchTo(record);
+                }
+            }
+        });
+
+        setOnItemLongClickListener(new OnItemLongClickListener() {
+            @Override
+            public boolean onItemLongClick(AdapterView<?> parent,
+                    View view, int position, long id) {
+                UserSwitcherController.UserRecord record = mAdapter.getItem(position);
+                if (record == null || record.isAddUser) {
+                    return false;
+                }
+                if (record.isGuest) {
+                    if (record.isCurrent) {
+                        mUserSwitcherController.switchTo(record);
+                    }
+                    return true;
+                }
+
+                new RemoveUserDialog(getContext(), record.info.id).show();
+                return true;
+            }
+        });
+    }
+
+    public void onUserSwitched(int newUserId) {
+        if (mPendingUserId == newUserId) {
+            // Bring up security view after user switch is completed.
+            post(new Runnable() {
+                @Override
+                public void run() {
+                    showOfflineAuthUi();
+                }
+            });
+        }
+        mPendingUserId = UserHandle.USER_NULL;
+    }
+
+    private void showOfflineAuthUi() {
+        // TODO: Show keyguard UI in-place.
+        mStatusBar.executeRunnableDismissingKeyguard(null, null, true, true);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        if (widthMode == MeasureSpec.UNSPECIFIED) {
+            setNumColumns(AUTO_FIT);
+        } else {
+            int columnWidth = Math.max(1, getRequestedColumnWidth());
+            int itemCount = getAdapter() == null ? 0 : getAdapter().getCount();
+            int numColumns = Math.max(1, Math.min(itemCount, widthSize / columnWidth));
+            setNumColumns(numColumns);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    private final class Adapter extends UserSwitcherController.BaseUserAdapter {
+        public Adapter(UserSwitcherController controller) {
+            super(controller);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
+                        (Context.LAYOUT_INFLATER_SERVICE);
+                convertView = inflater.inflate(R.layout.fullscreen_user_pod, null);
+            }
+            UserSwitcherController.UserRecord record = getItem(position);
+
+            TextView nameView = (TextView) convertView.findViewById(R.id.user_name);
+            if (record != null) {
+                nameView.setText(getName(getContext(), record));
+                convertView.setActivated(record.isCurrent);
+            } else {
+                nameView.setText("Unknown");
+            }
+
+            ImageView iconView = (ImageView) convertView.findViewById(R.id.user_avatar);
+            if (record == null || record.picture == null) {
+                iconView.setImageDrawable(getDrawable(getContext(), record));
+            } else {
+                iconView.setImageBitmap(record.picture);
+            }
+
+            return convertView;
+        }
+    }
+
+    private final class RemoveUserDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        private final int mUserId;
+
+        public RemoveUserDialog(Context context, int userId) {
+            super(context);
+            setTitle(R.string.user_remove_user_title);
+            setMessage(context.getString(R.string.user_remove_user_message));
+            setButton(DialogInterface.BUTTON_NEGATIVE,
+                    context.getString(android.R.string.cancel), this);
+            setButton(DialogInterface.BUTTON_POSITIVE,
+                    context.getString(R.string.user_remove_user_remove), this);
+            setCanceledOnTouchOutside(false);
+            mUserId = userId;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == BUTTON_NEGATIVE) {
+                cancel();
+            } else {
+                dismiss();
+                mUserSwitcherController.removeUserId(mUserId);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 0635847..b487fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -137,6 +137,7 @@
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.statusbar.policy.CastControllerImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.policy.FullscreenUserSwitcher;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.HotspotControllerImpl;
 import com.android.systemui.statusbar.policy.KeyButtonView;
@@ -270,6 +271,7 @@
     KeyguardMonitor mKeyguardMonitor;
     BrightnessMirrorController mBrightnessMirrorController;
     AccessibilityController mAccessibilityController;
+    FullscreenUserSwitcher mFullscreenUserSwitcher;
 
     int mNaturalBarHeight = -1;
 
@@ -860,11 +862,17 @@
         if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
             mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
                     mHandler);
+            if (mUserSwitcherController.useFullscreenUserSwitcher()) {
+                mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
+                        (ViewStub) mStatusBarWindow.findViewById(
+                                R.id.fullscreen_user_switcher_stub));
+            } else {
+                // Fullscreen user switcher does not show keyguard. Hence no KeyguardUserSwitcher.
+                mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
+                        (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
+                        mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
+            }
         }
-        mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
-                (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
-                mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
-
 
         // Set up the quick settings tile panel
         mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
@@ -1703,8 +1711,7 @@
 
         final boolean hasArtwork = artworkBitmap != null;
 
-        if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
-                && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+        if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && mState != StatusBarState.SHADE) {
             // time to show some art!
             if (mBackdrop.getVisibility() != View.VISIBLE) {
                 mBackdrop.setVisibility(View.VISIBLE);
@@ -2167,8 +2174,7 @@
 
     public void animateCollapsePanels(int flags, boolean force, boolean delayed,
             float speedUpFactor) {
-        if (!force &&
-                (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+        if (!force && mState != StatusBarState.SHADE) {
             runPostCollapseRunnables();
             return;
         }
@@ -2991,6 +2997,9 @@
         resetUserSetupObserver();
         setControllerUsers();
         mAssistManager.onUserSwitched(newUserId);
+        if (mFullscreenUserSwitcher != null) {
+            mFullscreenUserSwitcher.onUserSwitched(newUserId);
+        }
     }
 
     private void setControllerUsers() {
@@ -3359,7 +3368,11 @@
             onLaunchTransitionFadingEnded();
         }
         mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
-        setBarState(StatusBarState.KEYGUARD);
+        if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
+            setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
+        } else {
+            setBarState(StatusBarState.KEYGUARD);
+        }
         updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
         if (!mDeviceInteractive) {
 
@@ -3368,7 +3381,11 @@
             // Keyguard.
             mNotificationPanel.setTouchDisabled(true);
         }
-        instantExpandNotificationsPanel();
+        if (mState == StatusBarState.KEYGUARD) {
+            instantExpandNotificationsPanel();
+        } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
+            instantCollapseNotificationPanel();
+        }
         mLeaveOpenOnKeyguardHide = false;
         if (mDraggedDownRow != null) {
             mDraggedDownRow.setUserLocked(false);
@@ -3553,12 +3570,18 @@
         if (mState == StatusBarState.KEYGUARD) {
             mKeyguardIndicationController.setVisible(true);
             mNotificationPanel.resetViews();
-            mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
+            if (mKeyguardUserSwitcher != null) {
+                mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
+            }
             mStatusBarView.removePendingHideExpandedRunnables();
         } else {
             mKeyguardIndicationController.setVisible(false);
-            mKeyguardUserSwitcher.setKeyguard(false,
-                    goingToFullShade || mState == StatusBarState.SHADE_LOCKED || fromShadeLocked);
+            if (mKeyguardUserSwitcher != null) {
+                mKeyguardUserSwitcher.setKeyguard(false,
+                        goingToFullShade ||
+                        mState == StatusBarState.SHADE_LOCKED ||
+                        fromShadeLocked);
+            }
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mScrimController.setKeyguardShowing(true);
@@ -3567,6 +3590,13 @@
             mScrimController.setKeyguardShowing(false);
             mIconPolicy.setKeyguardShowing(false);
         }
+        if (mFullscreenUserSwitcher != null) {
+            if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
+                mFullscreenUserSwitcher.show();
+            } else {
+                mFullscreenUserSwitcher.hide();
+            }
+        }
         mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
         updateDozingState();
         updatePublicMode();
@@ -3634,8 +3664,7 @@
     }
 
     public boolean onSpacePressed() {
-        if (mDeviceInteractive
-                && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+        if (mDeviceInteractive && mState != StatusBarState.SHADE) {
             animateCollapsePanels(
                     CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java
new file mode 100644
index 0000000..fd8852e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.view.View;
+import android.view.ViewStub;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.UserGridView;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+
+/**
+ * Manages the fullscreen user switcher.
+ */
+public class FullscreenUserSwitcher {
+
+    private View mContainer;
+    private UserGridView mUserGridView;
+    private UserSwitcherController mUserSwitcherController;
+
+    public FullscreenUserSwitcher(PhoneStatusBar statusBar,
+            UserSwitcherController userSwitcherController,
+            ViewStub containerStub) {
+        mUserSwitcherController = userSwitcherController;
+        mContainer = containerStub.inflate();
+        mUserGridView = (UserGridView) mContainer.findViewById(R.id.user_grid);
+        mUserGridView.init(statusBar, mUserSwitcherController);
+    }
+
+    public void onUserSwitched(int newUserId) {
+        mUserGridView.onUserSwitched(newUserId);
+    }
+
+    public void show() {
+        mContainer.setVisibility(View.VISIBLE);
+    }
+
+    public void hide() {
+        mContainer.setVisibility(View.GONE);
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index f02f493..564a197 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -32,6 +32,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -189,7 +190,7 @@
                         guestRecord = new UserRecord(info, null /* picture */,
                                 true /* isGuest */, isCurrent, false /* isAddUser */,
                                 false /* isRestricted */);
-                    } else if (info.supportsSwitchToByUser()) {
+                    } else if (info.isEnabled() && info.supportsSwitchToByUser()) {
                         Bitmap picture = bitmaps.get(info.id);
                         if (picture == null) {
                             picture = mUserManager.getUserIcon(info.id);
@@ -272,6 +273,35 @@
         return mSimpleUserSwitcher;
     }
 
+    public boolean useFullscreenUserSwitcher() {
+        // Use adb to override:
+        // adb shell settings put system enable_fullscreen_user_switcher 0  # Turn it off.
+        // adb shell settings put system enable_fullscreen_user_switcher 1  # Turn it on.
+        // Restart SystemUI or adb reboot.
+        final int DEFAULT = -1;
+        final int overrideUseFullscreenUserSwitcher =
+                Settings.System.getInt(mContext.getContentResolver(),
+                        "enable_fullscreen_user_switcher", DEFAULT);
+        if (overrideUseFullscreenUserSwitcher != DEFAULT) {
+            return overrideUseFullscreenUserSwitcher != 0;
+        }
+        // Otherwise default to the build setting.
+        return mContext.getResources().getBoolean(R.bool.enable_fullscreen_user_switcher);
+    }
+
+    public void removeUserId(int userId) {
+        if (userId == UserHandle.USER_SYSTEM) {
+            Log.w(TAG, "User " + userId + " could not removed.");
+            return;
+        }
+        if (ActivityManager.getCurrentUser() == userId) {
+            switchToUserId(UserHandle.USER_SYSTEM);
+        }
+        if (mUserManager.removeUser(userId)) {
+            refreshUsers(UserHandle.USER_NULL);
+        }
+    }
+
     public void switchTo(UserRecord record) {
         int id;
         if (record.isGuest && record.info == null) {