Loading src/com/android/settings/users/UserSettings.java +8 −4 Original line number Diff line number Diff line Loading @@ -344,14 +344,18 @@ public class UserSettings extends SettingsPreferenceFragment @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { int pos = 0; UserManager um = getContext().getSystemService(UserManager.class); boolean allowRemoveUser = !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER); boolean canSwitchUsers = um.canSwitchUsers(); if (!mUserCaps.mIsAdmin && allowRemoveUser && canSwitchUsers) { final boolean canSwitchUsers = mUserManager.canSwitchUsers(); if (!mUserCaps.mIsAdmin && canSwitchUsers) { String nickname = mUserManager.getUserName(); MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++, getResources().getString(R.string.user_remove_user_menu, nickname)); removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); final EnforcedAdmin disallowRemoveUserAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getContext(), UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId()); RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getContext(), removeThisUser, disallowRemoveUserAdmin); } super.onCreateOptionsMenu(menu, inflater); } Loading tests/robotests/src/com/android/settings/users/UserSettingsTest.java +92 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.settings.users; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading @@ -26,12 +29,19 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import androidx.fragment.app.FragmentActivity; import androidx.preference.Preference; Loading @@ -44,18 +54,30 @@ import com.android.settings.R; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.testutils.Robolectric; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.RestrictedPreference; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; import java.util.Collections; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) @Config( shadows = { ShadowUserManager.class, ShadowDevicePolicyManager.class }) public class UserSettingsTest { private static final String KEY_USER_GUEST = "user_guest"; Loading Loading @@ -91,7 +113,8 @@ public class UserSettingsTest { mUserCapabilities = UserCapabilities.create(mContext); when((Object) mActivity.getSystemService(UserManager.class)).thenReturn(mUserManager); doReturn(mActivity).when(mFragment).getActivity(); doReturn(mContext).when(mFragment).getContext(); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); mProvisioned = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0); final SharedPreferences prefs = mock(SharedPreferences .class); Loading Loading @@ -209,7 +232,75 @@ public class UserSettingsTest { mFragment.updateUserList(); verify(addUser, never()).setVisible(true); } @Test public void withDisallowRemoveUser_ShouldDisableRemoveUser() { // TODO(b/115781615): Tidy robolectric tests // Arrange final int userId = UserHandle.myUserId(); final List<UserManager.EnforcingUser> enforcingUsers = Collections.singletonList( new UserManager.EnforcingUser(userId, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) ); ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_REMOVE_USER, UserHandle.of(userId), enforcingUsers); ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser( new ComponentName("test", "test")); doReturn(true).when(mUserManager).canSwitchUsers(); mUserCapabilities.mIsAdmin = false; ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities); ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager); Menu menu = mock(Menu.class); MenuItem menuItem = mock(MenuItem.class); final String title = "title"; doReturn(title).when(menuItem).getTitle(); doReturn(menuItem).when(menu).add( anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); // Act mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); // Assert // Expect that the click will be overridden and the color will be faded // (by RestrictedLockUtilsInternal) verify(menuItem).setOnMenuItemClickListener(notNull()); SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); verify(menuItem).setTitle(AdditionalMatchers.not(eq(defaultTitle))); } @Test public void withoutDisallowRemoveUser_ShouldNotDisableRemoveUser() { // Arrange doReturn(true).when(mUserManager).canSwitchUsers(); mUserCapabilities.mIsAdmin = false; ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities); ReflectionHelpers.setField(mFragment, "mUserManager", mock(UserManager.class)); Menu menu = mock(Menu.class); MenuItem menuItem = mock(MenuItem.class); final String title = "title"; doReturn(title).when(menuItem).getTitle(); doReturn(menuItem).when(menu).add( anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); // Act mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); // Assert // Expect that a click listener will not be added and the title will not be changed verify(menuItem, never()).setOnMenuItemClickListener(notNull()); SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); verify(menuItem, never()).setTitle(AdditionalMatchers.not(eq(defaultTitle))); } @Test Loading Loading
src/com/android/settings/users/UserSettings.java +8 −4 Original line number Diff line number Diff line Loading @@ -344,14 +344,18 @@ public class UserSettings extends SettingsPreferenceFragment @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { int pos = 0; UserManager um = getContext().getSystemService(UserManager.class); boolean allowRemoveUser = !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER); boolean canSwitchUsers = um.canSwitchUsers(); if (!mUserCaps.mIsAdmin && allowRemoveUser && canSwitchUsers) { final boolean canSwitchUsers = mUserManager.canSwitchUsers(); if (!mUserCaps.mIsAdmin && canSwitchUsers) { String nickname = mUserManager.getUserName(); MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++, getResources().getString(R.string.user_remove_user_menu, nickname)); removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); final EnforcedAdmin disallowRemoveUserAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getContext(), UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId()); RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getContext(), removeThisUser, disallowRemoveUserAdmin); } super.onCreateOptionsMenu(menu, inflater); } Loading
tests/robotests/src/com/android/settings/users/UserSettingsTest.java +92 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.settings.users; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading @@ -26,12 +29,19 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import androidx.fragment.app.FragmentActivity; import androidx.preference.Preference; Loading @@ -44,18 +54,30 @@ import com.android.settings.R; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.testutils.Robolectric; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.RestrictedPreference; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; import java.util.Collections; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) @Config( shadows = { ShadowUserManager.class, ShadowDevicePolicyManager.class }) public class UserSettingsTest { private static final String KEY_USER_GUEST = "user_guest"; Loading Loading @@ -91,7 +113,8 @@ public class UserSettingsTest { mUserCapabilities = UserCapabilities.create(mContext); when((Object) mActivity.getSystemService(UserManager.class)).thenReturn(mUserManager); doReturn(mActivity).when(mFragment).getActivity(); doReturn(mContext).when(mFragment).getContext(); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); mProvisioned = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0); final SharedPreferences prefs = mock(SharedPreferences .class); Loading Loading @@ -209,7 +232,75 @@ public class UserSettingsTest { mFragment.updateUserList(); verify(addUser, never()).setVisible(true); } @Test public void withDisallowRemoveUser_ShouldDisableRemoveUser() { // TODO(b/115781615): Tidy robolectric tests // Arrange final int userId = UserHandle.myUserId(); final List<UserManager.EnforcingUser> enforcingUsers = Collections.singletonList( new UserManager.EnforcingUser(userId, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) ); ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_REMOVE_USER, UserHandle.of(userId), enforcingUsers); ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser( new ComponentName("test", "test")); doReturn(true).when(mUserManager).canSwitchUsers(); mUserCapabilities.mIsAdmin = false; ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities); ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager); Menu menu = mock(Menu.class); MenuItem menuItem = mock(MenuItem.class); final String title = "title"; doReturn(title).when(menuItem).getTitle(); doReturn(menuItem).when(menu).add( anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); // Act mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); // Assert // Expect that the click will be overridden and the color will be faded // (by RestrictedLockUtilsInternal) verify(menuItem).setOnMenuItemClickListener(notNull()); SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); verify(menuItem).setTitle(AdditionalMatchers.not(eq(defaultTitle))); } @Test public void withoutDisallowRemoveUser_ShouldNotDisableRemoveUser() { // Arrange doReturn(true).when(mUserManager).canSwitchUsers(); mUserCapabilities.mIsAdmin = false; ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities); ReflectionHelpers.setField(mFragment, "mUserManager", mock(UserManager.class)); Menu menu = mock(Menu.class); MenuItem menuItem = mock(MenuItem.class); final String title = "title"; doReturn(title).when(menuItem).getTitle(); doReturn(menuItem).when(menu).add( anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); // Act mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); // Assert // Expect that a click listener will not be added and the title will not be changed verify(menuItem, never()).setOnMenuItemClickListener(notNull()); SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); verify(menuItem, never()).setTitle(AdditionalMatchers.not(eq(defaultTitle))); } @Test Loading