Add a switchbar to turn off multi-user feature entirely

Change-Id: Ibf88bf37899af5065c68aeb2337acd4ee48bc13c
Fixes: 72319180
Test: robotest on new controller. Manual test on UserSettings fragment.
This commit is contained in:
Fan Zhang
2018-06-05 15:36:40 -07:00
parent ddd9283ee0
commit c39238c63f
12 changed files with 352 additions and 100 deletions

View File

@@ -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"

View File

@@ -21,7 +21,6 @@ package com.android.settings.core;
*/
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 DATA_USAGE_SETTINGS_V2 = "settings_data_usage_v2";
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";

View File

@@ -29,7 +29,6 @@ import com.android.settings.gestures.DoubleTapScreenPreferenceController;
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 @@ public class LockscreenDashboardFragment extends DashboardFragment
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 @@ public class LockscreenDashboardFragment extends DashboardFragment
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;

View File

@@ -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);
}
}

View File

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

View File

@@ -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;
}
}

View File

@@ -22,6 +22,7 @@ import android.content.pm.UserInfo;
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 @@ public class UserCapabilities {
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 class UserCapabilities {
}
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 @@ public class UserCapabilities {
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);
}

View File

@@ -48,13 +48,13 @@ import android.view.Menu;
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.dashboard.SummaryLoader;
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 java.util.List;
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 @@ import androidx.preference.PreferenceScreen;
*/
@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 @@ public class UserSettings extends SettingsPreferenceFragment
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;
@@ -198,20 +203,37 @@ public class UserSettings extends SettingsPreferenceFragment
return MetricsEvent.USER;
}
@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 @@ public class UserSettings extends SettingsPreferenceFragment
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 @@ public class UserSettings extends SettingsPreferenceFragment
activity.registerReceiverAsUser(
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
loadProfile();
updateUserList();
updateUI();
mShouldUpdateUserList = false;
}
@@ -280,9 +301,7 @@ public class UserSettings extends SettingsPreferenceFragment
}
if (mShouldUpdateUserList) {
mUserCaps.updateAddUserCapabilities(getActivity());
loadProfile();
updateUserList();
updateUI();
}
}
@@ -343,6 +362,17 @@ public class UserSettings extends SettingsPreferenceFragment
}
}
@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 @@ public class UserSettings extends SettingsPreferenceFragment
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 @@ public class UserSettings extends SettingsPreferenceFragment
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 @@ public class UserSettings extends SettingsPreferenceFragment
// 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 @@ public class UserSettings extends SettingsPreferenceFragment
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
}
}
}
private int getMaxRealUsers() {
@@ -1190,8 +1231,7 @@ public class UserSettings extends SettingsPreferenceFragment
@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);

View File

@@ -47,6 +47,8 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
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 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
mRestrictionSources.clear();
mManagedProfiles.clear();
mIsQuietModeEnabled = false;
mUserSwitchEnabled = false;
}
public void setUserInfo(int userHandle, UserInfo userInfo) {
@@ -136,4 +139,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
public void setProfileIdsWithDisabled(int[] profileIds) {
profileIdsForUser = profileIds;
}
@Implementation
public boolean isUserSwitcherEnabled() {
return mUserSwitchEnabled;
}
public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
mUserSwitchEnabled = userSwitchEnabled;
}
}

View File

@@ -17,58 +17,59 @@ package com.android.settings.users;
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());

View File

@@ -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);
}
}

View File

@@ -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 @@ public class UserCapabilitiesTest {
}
@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();
}
}