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
diff --git a/res/xml/user_settings.xml b/res/xml/user_settings.xml
index 5cafa1a..b3dc2ea 100644
--- a/res/xml/user_settings.xml
+++ b/res/xml/user_settings.xml
@@ -43,6 +43,12 @@
android:icon="@drawable/ic_add_40dp"
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
android:key="user_settings_add_users_when_locked"
android:title="@string/user_add_on_lockscreen_menu"
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 096b6ee..2ad0ed0 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -115,6 +115,7 @@
private static final String KEY_USER_GUEST = "user_guest";
private static final String KEY_ADD_GUEST = "guest_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_MULTIUSER_TOP_INTRO = "multiuser_top_intro";
@@ -165,10 +166,13 @@
@VisibleForTesting
RestrictedPreference mAddUser;
@VisibleForTesting
+ RestrictedPreference mAddSupervisedUser;
+ @VisibleForTesting
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
private int mRemovingUserId = -1;
private boolean mAddingUser;
private boolean mGuestUserAutoCreated;
+ private String mConfigSupervisedUserCreationPackage;
private String mAddingUserName;
private UserCapabilities mUserCaps;
private boolean mShouldUpdateUserList = true;
@@ -300,6 +304,10 @@
}
mAddUser.setOnPreferenceClickListener(this);
+ setConfigSupervisedUserCreationPackage();
+ mAddSupervisedUser = findPreference(KEY_ADD_SUPERVISED_USER);
+ mAddSupervisedUser.setOnPreferenceClickListener(this);
+
activity.registerReceiverAsUser(
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
@@ -491,6 +499,14 @@
}
}
+ private void onAddSupervisedUserClicked() {
+ final Intent intent = new Intent()
+ .setAction(UserManager.ACTION_CREATE_SUPERVISED_USER)
+ .setPackage(mConfigSupervisedUserCreationPackage);
+
+ startActivity(intent);
+ }
+
private void onRemoveUserClicked(int userId) {
synchronized (mUserLock) {
if (mRemovingUserId == -1 && !mAddingUser) {
@@ -1058,6 +1074,7 @@
updateAddGuest(context, users.stream().anyMatch(UserInfo::isGuest));
updateAddUser(context);
+ updateAddSupervisedUser(context);
if (!mUserCaps.mUserSwitcherEnabled) {
return;
@@ -1070,6 +1087,12 @@
}
+ @VisibleForTesting
+ void setConfigSupervisedUserCreationPackage() {
+ mConfigSupervisedUserCreationPackage = getPrefContext().getString(
+ com.android.internal.R.string.config_supervisedUserCreationPackage);
+ }
+
private boolean isCurrentUserGuest() {
return mUserCaps.mIsGuest;
}
@@ -1100,28 +1123,41 @@
}
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)
&& WizardManagerHelper.isDeviceProvisioned(context)
&& mUserCaps.mUserSwitcherEnabled) {
- mAddUser.setVisible(true);
- mAddUser.setSelectable(true);
+ addUser.setVisible(true);
+ addUser.setSelectable(true);
final boolean canAddMoreUsers =
mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY)
- || (mUserCaps.mCanAddRestrictedProfile
+ || (canAddRestrictedProfile
&& mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_RESTRICTED));
- mAddUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
+ addUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
if (!canAddMoreUsers) {
- mAddUser.setSummary(
+ addUser.setSummary(
getString(R.string.user_add_max_count, getRealUsersCount()));
} else {
- mAddUser.setSummary(null);
+ addUser.setSummary(null);
}
- if (mAddUser.isEnabled()) {
- mAddUser.setDisabledByAdmin(
+ if (addUser.isEnabled()) {
+ addUser.setDisabledByAdmin(
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
}
} else {
- mAddUser.setVisible(false);
+ addUser.setVisible(false);
}
}
@@ -1206,6 +1242,9 @@
onAddUserClicked(USER_TYPE_USER);
}
return true;
+ } else if (pref == mAddSupervisedUser) {
+ onAddSupervisedUserClicked();
+ return true;
} else if (pref == mAddGuest) {
mAddGuest.setEnabled(false); // prevent multiple tap issue
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_USER_GUEST_ADD);
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 9d35797..d8f3959 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -59,6 +59,7 @@
import com.android.settings.SettingsActivity;
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.ShadowUserManager;
import com.android.settingslib.RestrictedLockUtils;
@@ -85,7 +86,11 @@
import java.util.List;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class})
+@Config(shadows = {
+ ShadowUserManager.class,
+ ShadowDevicePolicyManager.class,
+ SettingsShadowResources.class,
+})
public class UserSettingsTest {
private static final String KEY_USER_GUEST = "user_guest";
@@ -111,6 +116,8 @@
@Mock
private RestrictedPreference mAddUserPreference;
@Mock
+ private RestrictedPreference mAddSupervisedUserPreference;
+ @Mock
private RestrictedPreference mAddGuestPreference;
@Mock
private UserManager mUserManager;
@@ -161,6 +168,7 @@
mFragment.mMePreference = mMePreference;
mFragment.mAddUser = mAddUserPreference;
+ mFragment.mAddSupervisedUser = mAddSupervisedUserPreference;
mFragment.mAddGuest = mAddGuestPreference;
mFragment.mUserListCategory = mock(PreferenceCategory.class);
}
@@ -169,6 +177,7 @@
public void tearDown() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue);
+ SettingsShadowResources.reset();
}
@Test
@@ -694,6 +703,36 @@
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) {
List<UserInfo> users = Arrays.asList(userInfo);
doReturn(users).when(mUserManager).getUsers();