Add settings entrypoint to add a supervised user
Bug: 205101183 Bug: 199868785 Test: croot && make RunSettingsRoboTests -j40 ROBOTEST_FILTER="com.android.settings.users.UserSettingsTest" Change-Id: Ie69786c81ec938f4c4108d7fc9c0874776331865
This commit is contained in:
@@ -43,6 +43,12 @@
|
|||||||
android:icon="@drawable/ic_add_40dp"
|
android:icon="@drawable/ic_add_40dp"
|
||||||
android:order="20"/>
|
android:order="20"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.RestrictedPreference
|
||||||
|
android:key="supervised_user_add"
|
||||||
|
android:title="@*android:string/supervised_user_creation_label"
|
||||||
|
android:icon="@*android:drawable/ic_add_supervised_user"
|
||||||
|
android:order="25"/>
|
||||||
|
|
||||||
<com.android.settingslib.RestrictedSwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="user_settings_add_users_when_locked"
|
android:key="user_settings_add_users_when_locked"
|
||||||
android:title="@string/user_add_on_lockscreen_menu"
|
android:title="@string/user_add_on_lockscreen_menu"
|
||||||
|
@@ -115,6 +115,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
private static final String KEY_USER_GUEST = "user_guest";
|
private static final String KEY_USER_GUEST = "user_guest";
|
||||||
private static final String KEY_ADD_GUEST = "guest_add";
|
private static final String KEY_ADD_GUEST = "guest_add";
|
||||||
private static final String KEY_ADD_USER = "user_add";
|
private static final String KEY_ADD_USER = "user_add";
|
||||||
|
private static final String KEY_ADD_SUPERVISED_USER = "supervised_user_add";
|
||||||
private static final String KEY_ADD_USER_WHEN_LOCKED = "user_settings_add_users_when_locked";
|
private static final String KEY_ADD_USER_WHEN_LOCKED = "user_settings_add_users_when_locked";
|
||||||
private static final String KEY_MULTIUSER_TOP_INTRO = "multiuser_top_intro";
|
private static final String KEY_MULTIUSER_TOP_INTRO = "multiuser_top_intro";
|
||||||
|
|
||||||
@@ -165,10 +166,13 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
RestrictedPreference mAddUser;
|
RestrictedPreference mAddUser;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
RestrictedPreference mAddSupervisedUser;
|
||||||
|
@VisibleForTesting
|
||||||
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
||||||
private int mRemovingUserId = -1;
|
private int mRemovingUserId = -1;
|
||||||
private boolean mAddingUser;
|
private boolean mAddingUser;
|
||||||
private boolean mGuestUserAutoCreated;
|
private boolean mGuestUserAutoCreated;
|
||||||
|
private String mConfigSupervisedUserCreationPackage;
|
||||||
private String mAddingUserName;
|
private String mAddingUserName;
|
||||||
private UserCapabilities mUserCaps;
|
private UserCapabilities mUserCaps;
|
||||||
private boolean mShouldUpdateUserList = true;
|
private boolean mShouldUpdateUserList = true;
|
||||||
@@ -300,6 +304,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
mAddUser.setOnPreferenceClickListener(this);
|
mAddUser.setOnPreferenceClickListener(this);
|
||||||
|
|
||||||
|
setConfigSupervisedUserCreationPackage();
|
||||||
|
mAddSupervisedUser = findPreference(KEY_ADD_SUPERVISED_USER);
|
||||||
|
mAddSupervisedUser.setOnPreferenceClickListener(this);
|
||||||
|
|
||||||
activity.registerReceiverAsUser(
|
activity.registerReceiverAsUser(
|
||||||
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
|
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
|
||||||
|
|
||||||
@@ -491,6 +499,14 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onAddSupervisedUserClicked() {
|
||||||
|
final Intent intent = new Intent()
|
||||||
|
.setAction(UserManager.ACTION_CREATE_SUPERVISED_USER)
|
||||||
|
.setPackage(mConfigSupervisedUserCreationPackage);
|
||||||
|
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
private void onRemoveUserClicked(int userId) {
|
private void onRemoveUserClicked(int userId) {
|
||||||
synchronized (mUserLock) {
|
synchronized (mUserLock) {
|
||||||
if (mRemovingUserId == -1 && !mAddingUser) {
|
if (mRemovingUserId == -1 && !mAddingUser) {
|
||||||
@@ -1058,6 +1074,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
|
|
||||||
updateAddGuest(context, users.stream().anyMatch(UserInfo::isGuest));
|
updateAddGuest(context, users.stream().anyMatch(UserInfo::isGuest));
|
||||||
updateAddUser(context);
|
updateAddUser(context);
|
||||||
|
updateAddSupervisedUser(context);
|
||||||
|
|
||||||
if (!mUserCaps.mUserSwitcherEnabled) {
|
if (!mUserCaps.mUserSwitcherEnabled) {
|
||||||
return;
|
return;
|
||||||
@@ -1070,6 +1087,12 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setConfigSupervisedUserCreationPackage() {
|
||||||
|
mConfigSupervisedUserCreationPackage = getPrefContext().getString(
|
||||||
|
com.android.internal.R.string.config_supervisedUserCreationPackage);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isCurrentUserGuest() {
|
private boolean isCurrentUserGuest() {
|
||||||
return mUserCaps.mIsGuest;
|
return mUserCaps.mIsGuest;
|
||||||
}
|
}
|
||||||
@@ -1100,28 +1123,41 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateAddUser(Context context) {
|
private void updateAddUser(Context context) {
|
||||||
|
updateAddUserCommon(context, mAddUser, mUserCaps.mCanAddRestrictedProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAddSupervisedUser(Context context) {
|
||||||
|
if (!TextUtils.isEmpty(mConfigSupervisedUserCreationPackage)) {
|
||||||
|
updateAddUserCommon(context, mAddSupervisedUser, false);
|
||||||
|
} else {
|
||||||
|
mAddSupervisedUser.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAddUserCommon(Context context, RestrictedPreference addUser,
|
||||||
|
boolean canAddRestrictedProfile) {
|
||||||
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin)
|
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin)
|
||||||
&& WizardManagerHelper.isDeviceProvisioned(context)
|
&& WizardManagerHelper.isDeviceProvisioned(context)
|
||||||
&& mUserCaps.mUserSwitcherEnabled) {
|
&& mUserCaps.mUserSwitcherEnabled) {
|
||||||
mAddUser.setVisible(true);
|
addUser.setVisible(true);
|
||||||
mAddUser.setSelectable(true);
|
addUser.setSelectable(true);
|
||||||
final boolean canAddMoreUsers =
|
final boolean canAddMoreUsers =
|
||||||
mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY)
|
mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY)
|
||||||
|| (mUserCaps.mCanAddRestrictedProfile
|
|| (canAddRestrictedProfile
|
||||||
&& mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_RESTRICTED));
|
&& mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_RESTRICTED));
|
||||||
mAddUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
|
addUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
|
||||||
if (!canAddMoreUsers) {
|
if (!canAddMoreUsers) {
|
||||||
mAddUser.setSummary(
|
addUser.setSummary(
|
||||||
getString(R.string.user_add_max_count, getRealUsersCount()));
|
getString(R.string.user_add_max_count, getRealUsersCount()));
|
||||||
} else {
|
} else {
|
||||||
mAddUser.setSummary(null);
|
addUser.setSummary(null);
|
||||||
}
|
}
|
||||||
if (mAddUser.isEnabled()) {
|
if (addUser.isEnabled()) {
|
||||||
mAddUser.setDisabledByAdmin(
|
addUser.setDisabledByAdmin(
|
||||||
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mAddUser.setVisible(false);
|
addUser.setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1206,6 +1242,9 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
onAddUserClicked(USER_TYPE_USER);
|
onAddUserClicked(USER_TYPE_USER);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (pref == mAddSupervisedUser) {
|
||||||
|
onAddSupervisedUserClicked();
|
||||||
|
return true;
|
||||||
} else if (pref == mAddGuest) {
|
} else if (pref == mAddGuest) {
|
||||||
mAddGuest.setEnabled(false); // prevent multiple tap issue
|
mAddGuest.setEnabled(false); // prevent multiple tap issue
|
||||||
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_USER_GUEST_ADD);
|
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_USER_GUEST_ADD);
|
||||||
|
@@ -59,6 +59,7 @@ import androidx.preference.PreferenceScreen;
|
|||||||
|
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SubSettings;
|
import com.android.settings.SubSettings;
|
||||||
|
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||||
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
@@ -85,7 +86,11 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class})
|
@Config(shadows = {
|
||||||
|
ShadowUserManager.class,
|
||||||
|
ShadowDevicePolicyManager.class,
|
||||||
|
SettingsShadowResources.class,
|
||||||
|
})
|
||||||
public class UserSettingsTest {
|
public class UserSettingsTest {
|
||||||
|
|
||||||
private static final String KEY_USER_GUEST = "user_guest";
|
private static final String KEY_USER_GUEST = "user_guest";
|
||||||
@@ -111,6 +116,8 @@ public class UserSettingsTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private RestrictedPreference mAddUserPreference;
|
private RestrictedPreference mAddUserPreference;
|
||||||
@Mock
|
@Mock
|
||||||
|
private RestrictedPreference mAddSupervisedUserPreference;
|
||||||
|
@Mock
|
||||||
private RestrictedPreference mAddGuestPreference;
|
private RestrictedPreference mAddGuestPreference;
|
||||||
@Mock
|
@Mock
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
@@ -161,6 +168,7 @@ public class UserSettingsTest {
|
|||||||
|
|
||||||
mFragment.mMePreference = mMePreference;
|
mFragment.mMePreference = mMePreference;
|
||||||
mFragment.mAddUser = mAddUserPreference;
|
mFragment.mAddUser = mAddUserPreference;
|
||||||
|
mFragment.mAddSupervisedUser = mAddSupervisedUserPreference;
|
||||||
mFragment.mAddGuest = mAddGuestPreference;
|
mFragment.mAddGuest = mAddGuestPreference;
|
||||||
mFragment.mUserListCategory = mock(PreferenceCategory.class);
|
mFragment.mUserListCategory = mock(PreferenceCategory.class);
|
||||||
}
|
}
|
||||||
@@ -169,6 +177,7 @@ public class UserSettingsTest {
|
|||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
Settings.Global.putInt(mContext.getContentResolver(),
|
Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue);
|
Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue);
|
||||||
|
SettingsShadowResources.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -694,6 +703,36 @@ public class UserSettingsTest {
|
|||||||
verify(mUserManager).getUsers();
|
verify(mUserManager).getUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setConfigSupervisedUserCreationPackage(String value) {
|
||||||
|
SettingsShadowResources.overrideResource(
|
||||||
|
com.android.internal.R.string.config_supervisedUserCreationPackage,
|
||||||
|
value
|
||||||
|
);
|
||||||
|
mFragment.setConfigSupervisedUserCreationPackage();
|
||||||
|
mUserCapabilities.mCanAddUser = true;
|
||||||
|
mFragment.updateUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addSupervisedUserOption_resourceIsDefined_shouldBeDisplayed() {
|
||||||
|
try {
|
||||||
|
setConfigSupervisedUserCreationPackage("test");
|
||||||
|
verify(mAddSupervisedUserPreference).setVisible(true);
|
||||||
|
} finally {
|
||||||
|
SettingsShadowResources.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addSupervisedUserOption_resourceIsNotDefined_shouldBeHidden() {
|
||||||
|
try {
|
||||||
|
setConfigSupervisedUserCreationPackage("");
|
||||||
|
verify(mAddSupervisedUserPreference).setVisible(false);
|
||||||
|
} finally {
|
||||||
|
SettingsShadowResources.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void givenUsers(UserInfo... userInfo) {
|
private void givenUsers(UserInfo... userInfo) {
|
||||||
List<UserInfo> users = Arrays.asList(userInfo);
|
List<UserInfo> users = Arrays.asList(userInfo);
|
||||||
doReturn(users).when(mUserManager).getUsers();
|
doReturn(users).when(mUserManager).getUsers();
|
||||||
|
Reference in New Issue
Block a user