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();
+ }
}