Merge "Add a switchbar to turn off multi-user feature entirely"
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index a3fcaee..2cd92c5 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -31,7 +31,8 @@
 
         <com.android.settingslib.RestrictedSwitchPreference
             android:key="security_lockscreen_add_users_when_locked"
-            android:title="@string/user_add_on_lockscreen_menu" />
+            android:title="@string/user_add_on_lockscreen_menu"
+            settings:controller="com.android.settings.users.AddUserWhenLockedPreferenceController" />
 
         <com.android.settingslib.RestrictedPreference
             android:key="owner_info_settings"
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 47da6cf..006bd70 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -21,7 +21,6 @@
  */
 public class FeatureFlags {
     public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
-    public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
     public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
     public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
 }
diff --git a/src/com/android/settings/security/LockscreenDashboardFragment.java b/src/com/android/settings/security/LockscreenDashboardFragment.java
index 9669863..eaaf51d 100644
--- a/src/com/android/settings/security/LockscreenDashboardFragment.java
+++ b/src/com/android/settings/security/LockscreenDashboardFragment.java
@@ -29,7 +29,6 @@
 import com.android.settings.gestures.PickupGesturePreferenceController;
 import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.users.AddUserWhenLockedPreferenceController;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
@@ -109,8 +108,6 @@
                         KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
         lifecycle.addObserver(notificationController);
         controllers.add(notificationController);
-        controllers.add(new AddUserWhenLockedPreferenceController(
-                context, KEY_ADD_USER_FROM_LOCK_SCREEN, lifecycle));
         mOwnerInfoPreferenceController =
                 new OwnerInfoPreferenceController(context, this, lifecycle);
         controllers.add(mOwnerInfoPreferenceController);
@@ -147,8 +144,6 @@
                         Context context) {
                     final List<AbstractPreferenceController> controllers = new ArrayList<>();
                     controllers.add(new LockScreenNotificationPreferenceController(context));
-                    controllers.add(new AddUserWhenLockedPreferenceController(context,
-                            KEY_ADD_USER_FROM_LOCK_SCREEN, null /* lifecycle */));
                     controllers.add(new OwnerInfoPreferenceController(
                             context, null /* fragment */, null /* lifecycle */));
                     return controllers;
diff --git a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
index bebc2d7..2a61cac 100644
--- a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
+++ b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
@@ -16,72 +16,53 @@
 package com.android.settings.users;
 
 import android.content.Context;
-import android.provider.Settings.Global;
+import android.provider.Settings;
+
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.RestrictedSwitchPreference;
+
 import androidx.preference.Preference;
 
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
+public class AddUserWhenLockedPreferenceController extends TogglePreferenceController {
 
-public class AddUserWhenLockedPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
-        LifecycleObserver, OnPause, OnResume {
-
-    private final String mPrefKey;
     private final UserCapabilities mUserCaps;
-    private boolean mShouldUpdateUserList;
 
-    public AddUserWhenLockedPreferenceController(Context context, String key, Lifecycle lifecycle) {
-        super(context);
-        mPrefKey = key;
+    public AddUserWhenLockedPreferenceController(Context context, String key) {
+        super(context, key);
         mUserCaps = UserCapabilities.create(context);
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
     }
 
     @Override
     public void updateState(Preference preference) {
-        RestrictedSwitchPreference restrictedSwitchPreference =
+        super.updateState(preference);
+        mUserCaps.updateAddUserCapabilities(mContext);
+        final RestrictedSwitchPreference restrictedSwitchPreference =
                 (RestrictedSwitchPreference) preference;
-        int value = Global.getInt(mContext.getContentResolver(), Global.ADD_USERS_WHEN_LOCKED, 0);
-        restrictedSwitchPreference.setChecked(value == 1);
         restrictedSwitchPreference.setDisabledByAdmin(
                 mUserCaps.disallowAddUser() ? mUserCaps.getEnforcedAdmin() : null);
+        restrictedSwitchPreference.setVisible(mUserCaps.mUserSwitcherEnabled);
     }
 
     @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        Boolean value = (Boolean) newValue;
-        Global.putInt(mContext.getContentResolver(),
-                Global.ADD_USERS_WHEN_LOCKED, value != null && value ? 1 : 0);
-        return true;
-    }
-
-    @Override
-    public void onPause() {
-        mShouldUpdateUserList = true;
-    }
-
-    @Override
-    public void onResume() {
-        if (mShouldUpdateUserList) {
-            mUserCaps.updateAddUserCapabilities(mContext);
+    public int getAvailabilityStatus() {
+        if (!mUserCaps.isAdmin()) {
+            return DISABLED_FOR_USER;
+        } else if (mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin()) {
+            return DISABLED_FOR_USER;
+        } else {
+            return mUserCaps.mUserSwitcherEnabled ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
         }
     }
 
     @Override
-    public boolean isAvailable() {
-        return mUserCaps.isAdmin() &&
-                (!mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin());
+    public boolean isChecked() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mPrefKey;
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.ADD_USERS_WHEN_LOCKED, isChecked ? 1 : 0);
     }
 }
diff --git a/src/com/android/settings/users/MultiUserFooterPreferenceController.java b/src/com/android/settings/users/MultiUserFooterPreferenceController.java
new file mode 100644
index 0000000..877df58
--- /dev/null
+++ b/src/com/android/settings/users/MultiUserFooterPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.settings.users;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.FooterPreferenceMixin;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+public class MultiUserFooterPreferenceController extends BasePreferenceController {
+
+    @VisibleForTesting
+    final UserCapabilities mUserCaps;
+
+    private FooterPreferenceMixin mFooterMixin;
+
+    public MultiUserFooterPreferenceController(Context context) {
+        super(context, "dummy_key");
+        mUserCaps = UserCapabilities.create(context);
+    }
+
+    public MultiUserFooterPreferenceController setFooterMixin(FooterPreferenceMixin footerMixin) {
+        mFooterMixin = footerMixin;
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return (mUserCaps.mEnabled && !mUserCaps.mUserSwitcherEnabled)
+                ? AVAILABLE_UNSEARCHABLE
+                : DISABLED_FOR_USER;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        mUserCaps.updateAddUserCapabilities(mContext);
+        final FooterPreference pref = mFooterMixin.createFooterPreference();
+        pref.setTitle(R.string.user_settings_footer_text);
+        pref.setVisible(isAvailable());
+    }
+}
diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java
new file mode 100644
index 0000000..9588f71
--- /dev/null
+++ b/src/com/android/settings/users/MultiUserSwitchBarController.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 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.settings.users;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.settings.widget.SwitchWidgetController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+public class MultiUserSwitchBarController implements SwitchWidgetController.OnSwitchChangeListener,
+        LifecycleObserver, OnStart, OnStop {
+
+    interface OnMultiUserSwitchChangedListener {
+        void onMultiUserSwitchChanged(boolean newState);
+    }
+
+    private static final String TAG = "MultiUserSwitchBarCtrl";
+    private final Context mContext;
+    private final SwitchWidgetController mSwitchBar;
+    private final UserCapabilities mUserCapabilities;
+    private final OnMultiUserSwitchChangedListener mListener;
+
+    MultiUserSwitchBarController(Context context, SwitchWidgetController switchBar,
+            OnMultiUserSwitchChangedListener listener) {
+        mContext = context;
+        mSwitchBar = switchBar;
+        mListener = listener;
+        mUserCapabilities = UserCapabilities.create(context);
+        mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled);
+        mSwitchBar.setEnabled(!mUserCapabilities.mDisallowSwitchUser
+                && !mUserCapabilities.mIsGuest && mUserCapabilities.isAdmin());
+        mSwitchBar.setListener(this);
+    }
+
+    @Override
+    public void onStart() {
+        mSwitchBar.startListening();
+    }
+
+    @Override
+    public void onStop() {
+        mSwitchBar.stopListening();
+    }
+
+    @Override
+    public boolean onSwitchToggled(boolean isChecked) {
+        Log.d(TAG, "Toggling multi-user feature enabled state to: " + isChecked);
+        final boolean success = Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.USER_SWITCHER_ENABLED, isChecked ? 1 : 0);
+        if (success && mListener != null) {
+            mListener.onMultiUserSwitchChanged(isChecked);
+        }
+        return success;
+    }
+}
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index f1bfae9..b9a2228 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -22,6 +22,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+
 import com.android.settings.Utils;
 import com.android.settingslib.RestrictedLockUtils;
 
@@ -31,13 +32,15 @@
     boolean mCanAddRestrictedProfile = true;
     boolean mIsAdmin;
     boolean mIsGuest;
+    boolean mUserSwitcherEnabled;
     boolean mCanAddGuest;
     boolean mDisallowAddUser;
     boolean mDisallowAddUserSetByAdmin;
     boolean mDisallowSwitchUser;
     RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
 
-    private UserCapabilities() {}
+    private UserCapabilities() {
+    }
 
     public static UserCapabilities create(Context context) {
         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -62,14 +65,15 @@
     }
 
     public void updateAddUserCapabilities(Context context) {
+        final UserManager userManager =
+                (UserManager) context.getSystemService(Context.USER_SERVICE);
         mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
                 UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
         final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
                 context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
-        mDisallowAddUserSetByAdmin =
-                mEnforcedAdmin != null && !hasBaseUserRestriction;
-        mDisallowAddUser =
-                (mEnforcedAdmin != null || hasBaseUserRestriction);
+        mDisallowAddUserSetByAdmin = mEnforcedAdmin != null && !hasBaseUserRestriction;
+        mDisallowAddUser = (mEnforcedAdmin != null || hasBaseUserRestriction);
+        mUserSwitcherEnabled = userManager.isUserSwitcherEnabled();
         mCanAddUser = true;
         if (!mIsAdmin || UserManager.getMaxSupportedUsers() < 2
                 || !UserManager.supportsMultipleUsers()
@@ -81,7 +85,6 @@
                 context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
         mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
 
-        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
     }
 
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index a33561b..c57d959 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -48,13 +48,13 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.SimpleAdapter;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.UserIcons;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.core.SubSettingLauncher;
@@ -62,6 +62,8 @@
 import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.SwitchBarController;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedPreference;
@@ -78,7 +80,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
 import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceClickListener;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
 
@@ -92,7 +93,9 @@
  */
 @SearchIndexable
 public class UserSettings extends SettingsPreferenceFragment
-        implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
+        implements Preference.OnPreferenceClickListener, View.OnClickListener,
+        MultiUserSwitchBarController.OnMultiUserSwitchChangedListener,
+        DialogInterface.OnDismissListener,
         EditUserInfoController.OnContentChangedCallback, Indexable {
 
     private static final String TAG = "UserSettings";
@@ -155,8 +158,10 @@
     private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
     private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
 
+    private MultiUserSwitchBarController mSwitchBarController;
     private EditUserInfoController mEditUserInfoController = new EditUserInfoController();
     private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
+    private MultiUserFooterPreferenceController mMultiUserFooterPreferenceController;
 
     // A place to cache the generated default avatar
     private Drawable mDefaultIconDrawable;
@@ -199,19 +204,36 @@
     }
 
     @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        // Assume we are in a SettingsActivity. This is only safe because we currently use
+        // SettingsActivity as base for all preference fragments.
+        final SettingsActivity activity = (SettingsActivity) getActivity();
+        final SwitchBar switchBar = activity.getSwitchBar();
+        mSwitchBarController = new MultiUserSwitchBarController(activity,
+                new SwitchBarController(switchBar), this /* listener */);
+        getLifecycle().addObserver(mSwitchBarController);
+        switchBar.show();
+    }
+
+    @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         addPreferencesFromResource(R.xml.user_settings);
         final Activity activity = getActivity();
-        if (!Utils.isDeviceProvisioned(getActivity())) {
+        if (!Utils.isDeviceProvisioned(activity)) {
             activity.finish();
             return;
         }
 
         mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
-                activity, KEY_ADD_USER_WHEN_LOCKED, getLifecycle());
+                activity, KEY_ADD_USER_WHEN_LOCKED);
+        mMultiUserFooterPreferenceController = new MultiUserFooterPreferenceController(activity)
+                .setFooterMixin(mFooterPreferenceMixin);
+
         final PreferenceScreen screen = getPreferenceScreen();
         mAddUserWhenLockedPreferenceController.displayPreference(screen);
+        mMultiUserFooterPreferenceController.displayPreference(screen);
 
         screen.findPreference(mAddUserWhenLockedPreferenceController.getPreferenceKey())
                 .setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
@@ -246,7 +268,7 @@
         mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
         mAddUser.useAdminDisabledSummary(false);
         // Determine if add user/profile button should be visible
-        if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(getActivity())) {
+        if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(activity)) {
             mAddUser.setVisible(true);
             mAddUser.setOnPreferenceClickListener(this);
             // change label to only mention user, if restricted profiles are not supported
@@ -260,8 +282,7 @@
         activity.registerReceiverAsUser(
                 mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
 
-        loadProfile();
-        updateUserList();
+        updateUI();
         mShouldUpdateUserList = false;
     }
 
@@ -280,9 +301,7 @@
         }
 
         if (mShouldUpdateUserList) {
-            mUserCaps.updateAddUserCapabilities(getActivity());
-            loadProfile();
-            updateUserList();
+            updateUI();
         }
     }
 
@@ -343,6 +362,17 @@
         }
     }
 
+    @Override
+    public void onMultiUserSwitchChanged(boolean newState) {
+        updateUI();
+    }
+
+    private void updateUI() {
+        mUserCaps.updateAddUserCapabilities(getActivity());
+        loadProfile();
+        updateUserList();
+    }
+
     /**
      * Loads profile information for the current user.
      */
@@ -909,8 +939,6 @@
             loadIconsAsync(missingIcons);
         }
 
-        // Remove everything from mUserListCategory and add new users.
-        mUserListCategory.removeAll();
         // If profiles are supported, mUserListCategory will have a special title
         if (mUserCaps.mCanAddRestrictedProfile) {
             mUserListCategory.setTitle(R.string.user_list_title);
@@ -918,6 +946,20 @@
             mUserListCategory.setTitle(null);
         }
 
+        // Remove everything from mUserListCategory and add new users.
+        mUserListCategory.removeAll();
+
+        // If multi-user is disabled, just show footer and return.
+        final Preference addUserOnLockScreen = getPreferenceScreen().findPreference(
+                mAddUserWhenLockedPreferenceController.getPreferenceKey());
+        mAddUserWhenLockedPreferenceController.updateState(addUserOnLockScreen);
+        mMultiUserFooterPreferenceController.updateState(null /* preference */);
+        mAddUser.setVisible(mUserCaps.mUserSwitcherEnabled);
+        mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
+        if (!mUserCaps.mUserSwitcherEnabled) {
+            return;
+        }
+
         for (UserPreference userPreference : userPreferences) {
             userPreference.setOrder(Preference.DEFAULT_ORDER);
             mUserListCategory.addPreference(userPreference);
@@ -925,7 +967,7 @@
 
         // Append Add user to the end of the list
         if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
-                Utils.isDeviceProvisioned(getActivity())) {
+                Utils.isDeviceProvisioned(context)) {
             boolean moreUsers = mUserManager.canAddMoreUsers();
             mAddUser.setEnabled(moreUsers && !mAddingUser);
             if (!moreUsers) {
@@ -938,7 +980,6 @@
                         mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
             }
         }
-
     }
 
     private int getMaxRealUsers() {
@@ -1190,8 +1231,7 @@
                 @Override
                 public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId) {
                     final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId);
-                    new AddUserWhenLockedPreferenceController(
-                            context, KEY_ADD_USER_WHEN_LOCKED, null /* lifecycle */)
+                    new AddUserWhenLockedPreferenceController(context, KEY_ADD_USER_WHEN_LOCKED)
                             .updateNonIndexableKeys(niks);
                     new AutoSyncDataPreferenceController(context, null /* parent */)
                             .updateNonIndexableKeys(niks);
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index df87536..753d159 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -47,6 +47,8 @@
     private final Set<Integer> mManagedProfiles = new HashSet<>();
     private boolean mIsQuietModeEnabled = false;
     private int[] profileIdsForUser;
+    private boolean mUserSwitchEnabled;
+
 
     @Resetter
     public void reset() {
@@ -56,6 +58,7 @@
         mRestrictionSources.clear();
         mManagedProfiles.clear();
         mIsQuietModeEnabled = false;
+        mUserSwitchEnabled = false;
     }
 
     public void setUserInfo(int userHandle, UserInfo userInfo) {
@@ -136,4 +139,13 @@
     public void setProfileIdsWithDisabled(int[] profileIds) {
         profileIdsForUser = profileIds;
     }
+
+    @Implementation
+    public boolean isUserSwitcherEnabled() {
+        return mUserSwitchEnabled;
+    }
+
+    public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
+        mUserSwitchEnabled = userSwitchEnabled;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
index 10b2acb..c2b1c9f 100644
--- a/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/users/AddUserWhenLockedPreferenceControllerTest.java
@@ -17,58 +17,59 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Answers.RETURNS_DEEP_STUBS;
-import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import androidx.lifecycle.LifecycleOwner;
 import android.content.Context;
 import android.content.pm.UserInfo;
-import android.os.UserManager;
 import android.provider.Settings.Global;
-import androidx.preference.PreferenceScreen;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
+import androidx.preference.PreferenceScreen;
+
 @RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowUserManager.class})
 public class AddUserWhenLockedPreferenceControllerTest {
 
     @Mock(answer = RETURNS_DEEP_STUBS)
     private PreferenceScreen mScreen;
     @Mock(answer = RETURNS_DEEP_STUBS)
     private UserInfo mUserInfo;
-    @Mock(answer = RETURNS_DEEP_STUBS)
-    private UserManager mUserManager;
 
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
     private Context mContext;
+    private ShadowUserManager mUserManager;
     private AddUserWhenLockedPreferenceController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowApplication shadowContext = ShadowApplication.getInstance();
-        shadowContext.setSystemService(Context.USER_SERVICE, mUserManager);
+        mUserManager = ShadowUserManager.getShadow();
         mContext = shadowContext.getApplicationContext();
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key", mLifecycle);
+        mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key");
+    }
+
+    @After
+    public void tearDown() {
+        mUserManager.reset();
     }
 
     @Test
     public void displayPref_NotAdmin_shouldNotDisplay() {
-        when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
+        mUserManager.setUserInfo(0, mUserInfo);
         when(mUserInfo.isAdmin()).thenReturn(false);
         final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
         when(preference.getKey()).thenReturn(mController.getPreferenceKey());
diff --git a/tests/robotests/src/com/android/settings/users/MultiUserFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/users/MultiUserFooterPreferenceControllerTest.java
new file mode 100644
index 0000000..f74de7a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/users/MultiUserFooterPreferenceControllerTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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.settings.users;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class MultiUserFooterPreferenceControllerTest {
+
+    private Context mContext;
+    private MultiUserFooterPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mController = new MultiUserFooterPreferenceController(mContext);
+    }
+
+    @Test
+    public void getAvailabilityStatus_multiUserOff_shouldReturnEnabled() {
+        mController.mUserCaps.mEnabled = true;
+        mController.mUserCaps.mUserSwitcherEnabled = false;
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_multiUserOn_shouldReturnDisabled() {
+        mController.mUserCaps.mEnabled = true;
+        mController.mUserCaps.mUserSwitcherEnabled = true;
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
index d85f2fa..c8d3685 100644
--- a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
@@ -17,36 +17,43 @@
 package com.android.settings.users;
 
 import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.UserHandle;
 import android.os.UserManager;
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 @RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowUserManager.class})
 public class UserCapabilitiesTest {
 
-    @Mock
     private Context mContext;
-    @Mock
-    private UserManager mUserManager;
+    private ShadowUserManager mUserManager;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        mContext = RuntimeEnvironment.application;
+        mUserManager = ShadowUserManager.getShadow();
+    }
+
+    @After
+    public void tearDown() {
+        mUserManager.reset();
     }
 
     @Test
-    public void disallowUserSwitchWhenRestrictionIsSet() {
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
+    public void disallowUserSwitch_restrictionIsSet_true() {
+        mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+                UserManager.DISALLOW_USER_SWITCH, true);
 
         UserCapabilities userCapabilities = UserCapabilities.create(mContext);
         userCapabilities.updateAddUserCapabilities(mContext);
@@ -55,12 +62,33 @@
     }
 
     @Test
-    public void allowUserSwitchWhenRestrictionIsNotSet() {
-        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
+    public void disallowUserSwitch_restrictionIsNotSet_false() {
+        mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+                UserManager.DISALLOW_USER_SWITCH, false);
 
         UserCapabilities userCapabilities = UserCapabilities.create(mContext);
         userCapabilities.updateAddUserCapabilities(mContext);
 
         assertThat(userCapabilities.mDisallowSwitchUser).isFalse();
     }
+
+    @Test
+    public void userSwitchEnabled_off() {
+        mUserManager.setUserSwitcherEnabled(false);
+
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        userCapabilities.updateAddUserCapabilities(mContext);
+
+        assertThat(userCapabilities.mUserSwitcherEnabled).isFalse();
+    }
+
+    @Test
+    public void userSwitchEnabled_on() {
+        mUserManager.setUserSwitcherEnabled(true);
+
+        final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+        userCapabilities.updateAddUserCapabilities(mContext);
+
+        assertThat(userCapabilities.mUserSwitcherEnabled).isTrue();
+    }
 }