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:
@@ -31,7 +31,8 @@
|
|||||||
|
|
||||||
<com.android.settingslib.RestrictedSwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="security_lockscreen_add_users_when_locked"
|
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
|
<com.android.settingslib.RestrictedPreference
|
||||||
android:key="owner_info_settings"
|
android:key="owner_info_settings"
|
||||||
|
@@ -21,7 +21,6 @@ package com.android.settings.core;
|
|||||||
*/
|
*/
|
||||||
public class FeatureFlags {
|
public class FeatureFlags {
|
||||||
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
|
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 BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
|
||||||
public static final String DATA_USAGE_SETTINGS_V2 = "settings_data_usage_v2";
|
public static final String DATA_USAGE_SETTINGS_V2 = "settings_data_usage_v2";
|
||||||
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
||||||
|
@@ -29,7 +29,6 @@ import com.android.settings.gestures.DoubleTapScreenPreferenceController;
|
|||||||
import com.android.settings.gestures.PickupGesturePreferenceController;
|
import com.android.settings.gestures.PickupGesturePreferenceController;
|
||||||
import com.android.settings.notification.LockScreenNotificationPreferenceController;
|
import com.android.settings.notification.LockScreenNotificationPreferenceController;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.users.AddUserWhenLockedPreferenceController;
|
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
@@ -109,8 +108,6 @@ public class LockscreenDashboardFragment extends DashboardFragment
|
|||||||
KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
|
KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
|
||||||
lifecycle.addObserver(notificationController);
|
lifecycle.addObserver(notificationController);
|
||||||
controllers.add(notificationController);
|
controllers.add(notificationController);
|
||||||
controllers.add(new AddUserWhenLockedPreferenceController(
|
|
||||||
context, KEY_ADD_USER_FROM_LOCK_SCREEN, lifecycle));
|
|
||||||
mOwnerInfoPreferenceController =
|
mOwnerInfoPreferenceController =
|
||||||
new OwnerInfoPreferenceController(context, this, lifecycle);
|
new OwnerInfoPreferenceController(context, this, lifecycle);
|
||||||
controllers.add(mOwnerInfoPreferenceController);
|
controllers.add(mOwnerInfoPreferenceController);
|
||||||
@@ -147,8 +144,6 @@ public class LockscreenDashboardFragment extends DashboardFragment
|
|||||||
Context context) {
|
Context context) {
|
||||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||||
controllers.add(new LockScreenNotificationPreferenceController(context));
|
controllers.add(new LockScreenNotificationPreferenceController(context));
|
||||||
controllers.add(new AddUserWhenLockedPreferenceController(context,
|
|
||||||
KEY_ADD_USER_FROM_LOCK_SCREEN, null /* lifecycle */));
|
|
||||||
controllers.add(new OwnerInfoPreferenceController(
|
controllers.add(new OwnerInfoPreferenceController(
|
||||||
context, null /* fragment */, null /* lifecycle */));
|
context, null /* fragment */, null /* lifecycle */));
|
||||||
return controllers;
|
return controllers;
|
||||||
|
@@ -16,72 +16,53 @@
|
|||||||
package com.android.settings.users;
|
package com.android.settings.users;
|
||||||
|
|
||||||
import android.content.Context;
|
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 androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
public class AddUserWhenLockedPreferenceController extends TogglePreferenceController {
|
||||||
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 AbstractPreferenceController
|
|
||||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
|
|
||||||
LifecycleObserver, OnPause, OnResume {
|
|
||||||
|
|
||||||
private final String mPrefKey;
|
|
||||||
private final UserCapabilities mUserCaps;
|
private final UserCapabilities mUserCaps;
|
||||||
private boolean mShouldUpdateUserList;
|
|
||||||
|
|
||||||
public AddUserWhenLockedPreferenceController(Context context, String key, Lifecycle lifecycle) {
|
public AddUserWhenLockedPreferenceController(Context context, String key) {
|
||||||
super(context);
|
super(context, key);
|
||||||
mPrefKey = key;
|
|
||||||
mUserCaps = UserCapabilities.create(context);
|
mUserCaps = UserCapabilities.create(context);
|
||||||
if (lifecycle != null) {
|
|
||||||
lifecycle.addObserver(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
RestrictedSwitchPreference restrictedSwitchPreference =
|
super.updateState(preference);
|
||||||
|
mUserCaps.updateAddUserCapabilities(mContext);
|
||||||
|
final RestrictedSwitchPreference restrictedSwitchPreference =
|
||||||
(RestrictedSwitchPreference) preference;
|
(RestrictedSwitchPreference) preference;
|
||||||
int value = Global.getInt(mContext.getContentResolver(), Global.ADD_USERS_WHEN_LOCKED, 0);
|
|
||||||
restrictedSwitchPreference.setChecked(value == 1);
|
|
||||||
restrictedSwitchPreference.setDisabledByAdmin(
|
restrictedSwitchPreference.setDisabledByAdmin(
|
||||||
mUserCaps.disallowAddUser() ? mUserCaps.getEnforcedAdmin() : null);
|
mUserCaps.disallowAddUser() ? mUserCaps.getEnforcedAdmin() : null);
|
||||||
|
restrictedSwitchPreference.setVisible(mUserCaps.mUserSwitcherEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public int getAvailabilityStatus() {
|
||||||
Boolean value = (Boolean) newValue;
|
if (!mUserCaps.isAdmin()) {
|
||||||
Global.putInt(mContext.getContentResolver(),
|
return DISABLED_FOR_USER;
|
||||||
Global.ADD_USERS_WHEN_LOCKED, value != null && value ? 1 : 0);
|
} else if (mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin()) {
|
||||||
return true;
|
return DISABLED_FOR_USER;
|
||||||
}
|
} else {
|
||||||
|
return mUserCaps.mUserSwitcherEnabled ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
mShouldUpdateUserList = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
if (mShouldUpdateUserList) {
|
|
||||||
mUserCaps.updateAddUserCapabilities(mContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isChecked() {
|
||||||
return mUserCaps.isAdmin() &&
|
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
(!mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin());
|
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPreferenceKey() {
|
public boolean setChecked(boolean isChecked) {
|
||||||
return mPrefKey;
|
return Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.ADD_USERS_WHEN_LOCKED, isChecked ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -22,6 +22,7 @@ import android.content.pm.UserInfo;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
|
|
||||||
@@ -31,13 +32,15 @@ public class UserCapabilities {
|
|||||||
boolean mCanAddRestrictedProfile = true;
|
boolean mCanAddRestrictedProfile = true;
|
||||||
boolean mIsAdmin;
|
boolean mIsAdmin;
|
||||||
boolean mIsGuest;
|
boolean mIsGuest;
|
||||||
|
boolean mUserSwitcherEnabled;
|
||||||
boolean mCanAddGuest;
|
boolean mCanAddGuest;
|
||||||
boolean mDisallowAddUser;
|
boolean mDisallowAddUser;
|
||||||
boolean mDisallowAddUserSetByAdmin;
|
boolean mDisallowAddUserSetByAdmin;
|
||||||
boolean mDisallowSwitchUser;
|
boolean mDisallowSwitchUser;
|
||||||
RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
|
RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
|
||||||
|
|
||||||
private UserCapabilities() {}
|
private UserCapabilities() {
|
||||||
|
}
|
||||||
|
|
||||||
public static UserCapabilities create(Context context) {
|
public static UserCapabilities create(Context context) {
|
||||||
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
@@ -62,14 +65,15 @@ public class UserCapabilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateAddUserCapabilities(Context context) {
|
public void updateAddUserCapabilities(Context context) {
|
||||||
|
final UserManager userManager =
|
||||||
|
(UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
|
mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
|
||||||
UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
||||||
final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
|
final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
|
||||||
context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
||||||
mDisallowAddUserSetByAdmin =
|
mDisallowAddUserSetByAdmin = mEnforcedAdmin != null && !hasBaseUserRestriction;
|
||||||
mEnforcedAdmin != null && !hasBaseUserRestriction;
|
mDisallowAddUser = (mEnforcedAdmin != null || hasBaseUserRestriction);
|
||||||
mDisallowAddUser =
|
mUserSwitcherEnabled = userManager.isUserSwitcherEnabled();
|
||||||
(mEnforcedAdmin != null || hasBaseUserRestriction);
|
|
||||||
mCanAddUser = true;
|
mCanAddUser = true;
|
||||||
if (!mIsAdmin || UserManager.getMaxSupportedUsers() < 2
|
if (!mIsAdmin || UserManager.getMaxSupportedUsers() < 2
|
||||||
|| !UserManager.supportsMultipleUsers()
|
|| !UserManager.supportsMultipleUsers()
|
||||||
@@ -81,7 +85,6 @@ public class UserCapabilities {
|
|||||||
context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
||||||
mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
|
mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
|
||||||
|
|
||||||
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
|
||||||
mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
|
mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,13 +48,13 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.SimpleAdapter;
|
import android.widget.SimpleAdapter;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.internal.util.UserIcons;
|
import com.android.internal.util.UserIcons;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.core.SubSettingLauncher;
|
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.password.ChooseLockGeneric;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.search.Indexable;
|
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;
|
||||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
import com.android.settingslib.RestrictedPreference;
|
import com.android.settingslib.RestrictedPreference;
|
||||||
@@ -78,7 +80,6 @@ import java.util.List;
|
|||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
|
||||||
import androidx.preference.PreferenceGroup;
|
import androidx.preference.PreferenceGroup;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
@@ -92,7 +93,9 @@ import androidx.preference.PreferenceScreen;
|
|||||||
*/
|
*/
|
||||||
@SearchIndexable
|
@SearchIndexable
|
||||||
public class UserSettings extends SettingsPreferenceFragment
|
public class UserSettings extends SettingsPreferenceFragment
|
||||||
implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
|
implements Preference.OnPreferenceClickListener, View.OnClickListener,
|
||||||
|
MultiUserSwitchBarController.OnMultiUserSwitchChangedListener,
|
||||||
|
DialogInterface.OnDismissListener,
|
||||||
EditUserInfoController.OnContentChangedCallback, Indexable {
|
EditUserInfoController.OnContentChangedCallback, Indexable {
|
||||||
|
|
||||||
private static final String TAG = "UserSettings";
|
private static final String TAG = "UserSettings";
|
||||||
@@ -155,8 +158,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
||||||
private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
|
private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
|
||||||
|
|
||||||
|
private MultiUserSwitchBarController mSwitchBarController;
|
||||||
private EditUserInfoController mEditUserInfoController = new EditUserInfoController();
|
private EditUserInfoController mEditUserInfoController = new EditUserInfoController();
|
||||||
private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
|
private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
|
||||||
|
private MultiUserFooterPreferenceController mMultiUserFooterPreferenceController;
|
||||||
|
|
||||||
// A place to cache the generated default avatar
|
// A place to cache the generated default avatar
|
||||||
private Drawable mDefaultIconDrawable;
|
private Drawable mDefaultIconDrawable;
|
||||||
@@ -198,20 +203,37 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
return MetricsEvent.USER;
|
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
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
addPreferencesFromResource(R.xml.user_settings);
|
addPreferencesFromResource(R.xml.user_settings);
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
if (!Utils.isDeviceProvisioned(getActivity())) {
|
if (!Utils.isDeviceProvisioned(activity)) {
|
||||||
activity.finish();
|
activity.finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
|
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();
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
mAddUserWhenLockedPreferenceController.displayPreference(screen);
|
mAddUserWhenLockedPreferenceController.displayPreference(screen);
|
||||||
|
mMultiUserFooterPreferenceController.displayPreference(screen);
|
||||||
|
|
||||||
screen.findPreference(mAddUserWhenLockedPreferenceController.getPreferenceKey())
|
screen.findPreference(mAddUserWhenLockedPreferenceController.getPreferenceKey())
|
||||||
.setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
|
.setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
|
||||||
@@ -246,7 +268,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
|
mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
|
||||||
mAddUser.useAdminDisabledSummary(false);
|
mAddUser.useAdminDisabledSummary(false);
|
||||||
// Determine if add user/profile button should be visible
|
// 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.setVisible(true);
|
||||||
mAddUser.setOnPreferenceClickListener(this);
|
mAddUser.setOnPreferenceClickListener(this);
|
||||||
// change label to only mention user, if restricted profiles are not supported
|
// change label to only mention user, if restricted profiles are not supported
|
||||||
@@ -260,8 +282,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
activity.registerReceiverAsUser(
|
activity.registerReceiverAsUser(
|
||||||
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
|
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
|
||||||
|
|
||||||
loadProfile();
|
updateUI();
|
||||||
updateUserList();
|
|
||||||
mShouldUpdateUserList = false;
|
mShouldUpdateUserList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,9 +301,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mShouldUpdateUserList) {
|
if (mShouldUpdateUserList) {
|
||||||
mUserCaps.updateAddUserCapabilities(getActivity());
|
updateUI();
|
||||||
loadProfile();
|
|
||||||
updateUserList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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.
|
* Loads profile information for the current user.
|
||||||
*/
|
*/
|
||||||
@@ -909,8 +939,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
loadIconsAsync(missingIcons);
|
loadIconsAsync(missingIcons);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove everything from mUserListCategory and add new users.
|
|
||||||
mUserListCategory.removeAll();
|
|
||||||
// If profiles are supported, mUserListCategory will have a special title
|
// If profiles are supported, mUserListCategory will have a special title
|
||||||
if (mUserCaps.mCanAddRestrictedProfile) {
|
if (mUserCaps.mCanAddRestrictedProfile) {
|
||||||
mUserListCategory.setTitle(R.string.user_list_title);
|
mUserListCategory.setTitle(R.string.user_list_title);
|
||||||
@@ -918,6 +946,20 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
mUserListCategory.setTitle(null);
|
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) {
|
for (UserPreference userPreference : userPreferences) {
|
||||||
userPreference.setOrder(Preference.DEFAULT_ORDER);
|
userPreference.setOrder(Preference.DEFAULT_ORDER);
|
||||||
mUserListCategory.addPreference(userPreference);
|
mUserListCategory.addPreference(userPreference);
|
||||||
@@ -925,7 +967,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
|
|
||||||
// Append Add user to the end of the list
|
// Append Add user to the end of the list
|
||||||
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
|
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
|
||||||
Utils.isDeviceProvisioned(getActivity())) {
|
Utils.isDeviceProvisioned(context)) {
|
||||||
boolean moreUsers = mUserManager.canAddMoreUsers();
|
boolean moreUsers = mUserManager.canAddMoreUsers();
|
||||||
mAddUser.setEnabled(moreUsers && !mAddingUser);
|
mAddUser.setEnabled(moreUsers && !mAddingUser);
|
||||||
if (!moreUsers) {
|
if (!moreUsers) {
|
||||||
@@ -938,7 +980,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxRealUsers() {
|
private int getMaxRealUsers() {
|
||||||
@@ -1190,8 +1231,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId) {
|
public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId) {
|
||||||
final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId);
|
final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId);
|
||||||
new AddUserWhenLockedPreferenceController(
|
new AddUserWhenLockedPreferenceController(context, KEY_ADD_USER_WHEN_LOCKED)
|
||||||
context, KEY_ADD_USER_WHEN_LOCKED, null /* lifecycle */)
|
|
||||||
.updateNonIndexableKeys(niks);
|
.updateNonIndexableKeys(niks);
|
||||||
new AutoSyncDataPreferenceController(context, null /* parent */)
|
new AutoSyncDataPreferenceController(context, null /* parent */)
|
||||||
.updateNonIndexableKeys(niks);
|
.updateNonIndexableKeys(niks);
|
||||||
|
@@ -47,6 +47,8 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
||||||
private boolean mIsQuietModeEnabled = false;
|
private boolean mIsQuietModeEnabled = false;
|
||||||
private int[] profileIdsForUser;
|
private int[] profileIdsForUser;
|
||||||
|
private boolean mUserSwitchEnabled;
|
||||||
|
|
||||||
|
|
||||||
@Resetter
|
@Resetter
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@@ -56,6 +58,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
mRestrictionSources.clear();
|
mRestrictionSources.clear();
|
||||||
mManagedProfiles.clear();
|
mManagedProfiles.clear();
|
||||||
mIsQuietModeEnabled = false;
|
mIsQuietModeEnabled = false;
|
||||||
|
mUserSwitchEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserInfo(int userHandle, UserInfo userInfo) {
|
public void setUserInfo(int userHandle, UserInfo userInfo) {
|
||||||
@@ -136,4 +139,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
public void setProfileIdsWithDisabled(int[] profileIds) {
|
public void setProfileIdsWithDisabled(int[] profileIds) {
|
||||||
profileIdsForUser = profileIds;
|
profileIdsForUser = profileIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public boolean isUserSwitcherEnabled() {
|
||||||
|
return mUserSwitchEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
|
||||||
|
mUserSwitchEnabled = userSwitchEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,58 +17,59 @@ package com.android.settings.users;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
|
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.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.os.UserManager;
|
|
||||||
import android.provider.Settings.Global;
|
import android.provider.Settings.Global;
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||||
import com.android.settingslib.RestrictedSwitchPreference;
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(shadows = {ShadowUserManager.class})
|
||||||
public class AddUserWhenLockedPreferenceControllerTest {
|
public class AddUserWhenLockedPreferenceControllerTest {
|
||||||
|
|
||||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||||
private PreferenceScreen mScreen;
|
private PreferenceScreen mScreen;
|
||||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||||
private UserInfo mUserInfo;
|
private UserInfo mUserInfo;
|
||||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
|
||||||
private UserManager mUserManager;
|
|
||||||
|
|
||||||
private LifecycleOwner mLifecycleOwner;
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
private ShadowUserManager mUserManager;
|
||||||
private AddUserWhenLockedPreferenceController mController;
|
private AddUserWhenLockedPreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
ShadowApplication shadowContext = ShadowApplication.getInstance();
|
ShadowApplication shadowContext = ShadowApplication.getInstance();
|
||||||
shadowContext.setSystemService(Context.USER_SERVICE, mUserManager);
|
mUserManager = ShadowUserManager.getShadow();
|
||||||
mContext = shadowContext.getApplicationContext();
|
mContext = shadowContext.getApplicationContext();
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key");
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
}
|
||||||
mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key", mLifecycle);
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mUserManager.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void displayPref_NotAdmin_shouldNotDisplay() {
|
public void displayPref_NotAdmin_shouldNotDisplay() {
|
||||||
when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
|
mUserManager.setUserInfo(0, mUserInfo);
|
||||||
when(mUserInfo.isAdmin()).thenReturn(false);
|
when(mUserInfo.isAdmin()).thenReturn(false);
|
||||||
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
|
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
|
||||||
when(preference.getKey()).thenReturn(mController.getPreferenceKey());
|
when(preference.getKey()).thenReturn(mController.getPreferenceKey());
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -17,36 +17,43 @@
|
|||||||
package com.android.settings.users;
|
package com.android.settings.users;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(shadows = {ShadowUserManager.class})
|
||||||
public class UserCapabilitiesTest {
|
public class UserCapabilitiesTest {
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@Mock
|
private ShadowUserManager mUserManager;
|
||||||
private UserManager mUserManager;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
mContext = RuntimeEnvironment.application;
|
||||||
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
|
mUserManager = ShadowUserManager.getShadow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mUserManager.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disallowUserSwitchWhenRestrictionIsSet() {
|
public void disallowUserSwitch_restrictionIsSet_true() {
|
||||||
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
|
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||||
|
UserManager.DISALLOW_USER_SWITCH, true);
|
||||||
|
|
||||||
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||||
userCapabilities.updateAddUserCapabilities(mContext);
|
userCapabilities.updateAddUserCapabilities(mContext);
|
||||||
@@ -55,12 +62,33 @@ public class UserCapabilitiesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allowUserSwitchWhenRestrictionIsNotSet() {
|
public void disallowUserSwitch_restrictionIsNotSet_false() {
|
||||||
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
|
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||||
|
UserManager.DISALLOW_USER_SWITCH, false);
|
||||||
|
|
||||||
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||||
userCapabilities.updateAddUserCapabilities(mContext);
|
userCapabilities.updateAddUserCapabilities(mContext);
|
||||||
|
|
||||||
assertThat(userCapabilities.mDisallowSwitchUser).isFalse();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user