diff --git a/res/xml/user_settings.xml b/res/xml/user_settings.xml index 5cafa1a977e..b3dc2ea583f 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"/> + + 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 @@ public class UserSettings extends SettingsPreferenceFragment } 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 @@ 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) { synchronized (mUserLock) { if (mRemovingUserId == -1 && !mAddingUser) { @@ -1058,6 +1074,7 @@ public class UserSettings extends SettingsPreferenceFragment updateAddGuest(context, users.stream().anyMatch(UserInfo::isGuest)); updateAddUser(context); + updateAddSupervisedUser(context); if (!mUserCaps.mUserSwitcherEnabled) { 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() { return mUserCaps.mIsGuest; } @@ -1100,28 +1123,41 @@ public class UserSettings extends SettingsPreferenceFragment } 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 @@ public class UserSettings extends SettingsPreferenceFragment 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 9d357977a6c..d8f3959c6d7 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 androidx.preference.PreferenceScreen; 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.Collections; 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 @@ public class UserSettingsTest { @Mock private RestrictedPreference mAddUserPreference; @Mock + private RestrictedPreference mAddSupervisedUserPreference; + @Mock private RestrictedPreference mAddGuestPreference; @Mock private UserManager mUserManager; @@ -161,6 +168,7 @@ public class UserSettingsTest { mFragment.mMePreference = mMePreference; mFragment.mAddUser = mAddUserPreference; + mFragment.mAddSupervisedUser = mAddSupervisedUserPreference; mFragment.mAddGuest = mAddGuestPreference; mFragment.mUserListCategory = mock(PreferenceCategory.class); } @@ -169,6 +177,7 @@ public class UserSettingsTest { public void tearDown() { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue); + SettingsShadowResources.reset(); } @Test @@ -694,6 +703,36 @@ public class UserSettingsTest { 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 users = Arrays.asList(userInfo); doReturn(users).when(mUserManager).getUsers();