Loading res/xml/security_settings_unification.xml +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/security_settings_title"> <SwitchPreference <com.android.settingslib.RestrictedSwitchPreference android:key="unification" android:title="@string/lock_settings_profile_unification_title" android:summary="@string/lock_settings_profile_unification_summary" Loading src/com/android/settings/security/SecuritySettings.java +18 −13 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComp import com.android.settings.widget.GearPreference; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.drawer.CategoryKey; import java.util.ArrayList; Loading Loading @@ -144,7 +145,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private ManagedLockPasswordProvider mManagedPasswordProvider; private SwitchPreference mVisiblePatternProfile; private SwitchPreference mUnifyProfile; private RestrictedSwitchPreference mUnifyProfile; private SwitchPreference mShowPassword; Loading Loading @@ -319,7 +320,7 @@ public class SecuritySettings extends SettingsPreferenceFragment mVisiblePatternProfile = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE); mUnifyProfile = (SwitchPreference) root.findPreference(KEY_UNIFICATION); mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION); // Append the rest of the settings addPreferencesFromResource(R.xml.security_settings_misc); Loading Loading @@ -560,12 +561,19 @@ public class SecuritySettings extends SettingsPreferenceFragment mLocationcontroller.updateSummary(); } private void updateUnificationPreference() { @VisibleForTesting void updateUnificationPreference() { if (mUnifyProfile != null) { mUnifyProfile.setChecked(!mLockPatternUtils.isSeparateProfileChallengeEnabled( final boolean separate = mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId); mUnifyProfile.setChecked(!separate); if (separate) { mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced( getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD, mProfileChallengeUserId)); } } } @Override public boolean onPreferenceTreeClick(Preference preference) { Loading Loading @@ -930,16 +938,13 @@ public class SecuritySettings extends SettingsPreferenceFragment .setPositiveButton( compliant ? R.string.lock_settings_profile_unification_dialog_confirm : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { (dialog, whichButton) -> { if (compliant) { parentFragment.launchConfirmDeviceLockForUnification(); } else { parentFragment.unifyUncompliantLocks(); } } } ) .setNegativeButton(R.string.cancel, null) .create(); Loading tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.settings.security; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; Loading @@ -29,7 +31,9 @@ import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager.EnforcingUser; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceScreen; Loading @@ -43,6 +47,9 @@ import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; import org.junit.Test; Loading @@ -55,12 +62,15 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import org.robolectric.util.ReflectionHelpers; import java.util.Arrays; import java.util.Collections; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = { ShadowLockPatternUtils.class ShadowLockPatternUtils.class, ShadowUserManager.class, }) public class SecuritySettingsTest { Loading Loading @@ -187,4 +197,49 @@ public class SecuritySettingsTest { assertThat(keys).containsAllIn(niks); } @Test public void testUnifyLockRestriction() { // Set up instance under test. final Context context = spy(RuntimeEnvironment.application); final SecuritySettings securitySettings = spy(new SecuritySettings()); when(securitySettings.getContext()).thenReturn(context); final int userId = 123; ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId); final LockPatternUtils utils = mock(LockPatternUtils.class); when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true); ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils); final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class); ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile); // Pretend that no admins enforce the restriction. ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_UNIFIED_PASSWORD, UserHandle.of(userId), Collections.emptyList()); securitySettings.updateUnificationPreference(); verify(unifyProfile).setDisabledByAdmin(null); reset(unifyProfile); // Pretend that the restriction is enforced by several admins. Having just one would // require more mocking of implementation details. final EnforcingUser enforcer1 = new EnforcingUser( userId, UserManager.RESTRICTION_SOURCE_PROFILE_OWNER); final EnforcingUser enforcer2 = new EnforcingUser( UserHandle.USER_SYSTEM, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_UNIFIED_PASSWORD, UserHandle.of(userId), Arrays.asList(enforcer1, enforcer2)); securitySettings.updateUnificationPreference(); verify(unifyProfile).setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN); } } tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +17 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager.EnforcingUser; import android.util.SparseArray; import org.robolectric.RuntimeEnvironment; Loading @@ -31,14 +32,18 @@ import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @Implements(UserManager.class) public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager { private SparseArray<UserInfo> mUserInfos = new SparseArray<>(); private boolean mAdminUser; private List<String> mRestrictions = new ArrayList<>(); private final List<String> mRestrictions = new ArrayList<>(); private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>(); public void setIsAdminUser(boolean isAdminUser) { mAdminUser = isAdminUser; Loading Loading @@ -91,4 +96,15 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager return (ShadowUserManager) Shadow.extract( RuntimeEnvironment.application.getSystemService(UserManager.class)); } @Implementation public List<EnforcingUser> getUserRestrictionSources( String restrictionKey, UserHandle userHandle) { return mRestrictionSources.get(restrictionKey + userHandle.getIdentifier()); } public void setUserRestrictionSources( String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers) { mRestrictionSources.put(restrictionKey + userHandle.getIdentifier(), enforcers); } } Loading
res/xml/security_settings_unification.xml +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/security_settings_title"> <SwitchPreference <com.android.settingslib.RestrictedSwitchPreference android:key="unification" android:title="@string/lock_settings_profile_unification_title" android:summary="@string/lock_settings_profile_unification_summary" Loading
src/com/android/settings/security/SecuritySettings.java +18 −13 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComp import com.android.settings.widget.GearPreference; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.drawer.CategoryKey; import java.util.ArrayList; Loading Loading @@ -144,7 +145,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private ManagedLockPasswordProvider mManagedPasswordProvider; private SwitchPreference mVisiblePatternProfile; private SwitchPreference mUnifyProfile; private RestrictedSwitchPreference mUnifyProfile; private SwitchPreference mShowPassword; Loading Loading @@ -319,7 +320,7 @@ public class SecuritySettings extends SettingsPreferenceFragment mVisiblePatternProfile = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE); mUnifyProfile = (SwitchPreference) root.findPreference(KEY_UNIFICATION); mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION); // Append the rest of the settings addPreferencesFromResource(R.xml.security_settings_misc); Loading Loading @@ -560,12 +561,19 @@ public class SecuritySettings extends SettingsPreferenceFragment mLocationcontroller.updateSummary(); } private void updateUnificationPreference() { @VisibleForTesting void updateUnificationPreference() { if (mUnifyProfile != null) { mUnifyProfile.setChecked(!mLockPatternUtils.isSeparateProfileChallengeEnabled( final boolean separate = mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId); mUnifyProfile.setChecked(!separate); if (separate) { mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced( getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD, mProfileChallengeUserId)); } } } @Override public boolean onPreferenceTreeClick(Preference preference) { Loading Loading @@ -930,16 +938,13 @@ public class SecuritySettings extends SettingsPreferenceFragment .setPositiveButton( compliant ? R.string.lock_settings_profile_unification_dialog_confirm : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { (dialog, whichButton) -> { if (compliant) { parentFragment.launchConfirmDeviceLockForUnification(); } else { parentFragment.unifyUncompliantLocks(); } } } ) .setNegativeButton(R.string.cancel, null) .create(); Loading
tests/robotests/src/com/android/settings/security/SecuritySettingsTest.java +56 −1 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.settings.security; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; Loading @@ -29,7 +31,9 @@ import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager.EnforcingUser; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceScreen; Loading @@ -43,6 +47,9 @@ import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedSwitchPreference; import org.junit.Before; import org.junit.Test; Loading @@ -55,12 +62,15 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import org.robolectric.util.ReflectionHelpers; import java.util.Arrays; import java.util.Collections; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = { ShadowLockPatternUtils.class ShadowLockPatternUtils.class, ShadowUserManager.class, }) public class SecuritySettingsTest { Loading Loading @@ -187,4 +197,49 @@ public class SecuritySettingsTest { assertThat(keys).containsAllIn(niks); } @Test public void testUnifyLockRestriction() { // Set up instance under test. final Context context = spy(RuntimeEnvironment.application); final SecuritySettings securitySettings = spy(new SecuritySettings()); when(securitySettings.getContext()).thenReturn(context); final int userId = 123; ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId); final LockPatternUtils utils = mock(LockPatternUtils.class); when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true); ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils); final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class); ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile); // Pretend that no admins enforce the restriction. ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_UNIFIED_PASSWORD, UserHandle.of(userId), Collections.emptyList()); securitySettings.updateUnificationPreference(); verify(unifyProfile).setDisabledByAdmin(null); reset(unifyProfile); // Pretend that the restriction is enforced by several admins. Having just one would // require more mocking of implementation details. final EnforcingUser enforcer1 = new EnforcingUser( userId, UserManager.RESTRICTION_SOURCE_PROFILE_OWNER); final EnforcingUser enforcer2 = new EnforcingUser( UserHandle.USER_SYSTEM, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); ShadowUserManager.getShadow().setUserRestrictionSources( UserManager.DISALLOW_UNIFIED_PASSWORD, UserHandle.of(userId), Arrays.asList(enforcer1, enforcer2)); securitySettings.updateUnificationPreference(); verify(unifyProfile).setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN); } }
tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +17 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager.EnforcingUser; import android.util.SparseArray; import org.robolectric.RuntimeEnvironment; Loading @@ -31,14 +32,18 @@ import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @Implements(UserManager.class) public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager { private SparseArray<UserInfo> mUserInfos = new SparseArray<>(); private boolean mAdminUser; private List<String> mRestrictions = new ArrayList<>(); private final List<String> mRestrictions = new ArrayList<>(); private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>(); public void setIsAdminUser(boolean isAdminUser) { mAdminUser = isAdminUser; Loading Loading @@ -91,4 +96,15 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager return (ShadowUserManager) Shadow.extract( RuntimeEnvironment.application.getSystemService(UserManager.class)); } @Implementation public List<EnforcingUser> getUserRestrictionSources( String restrictionKey, UserHandle userHandle) { return mRestrictionSources.get(restrictionKey + userHandle.getIdentifier()); } public void setUserRestrictionSources( String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers) { mRestrictionSources.put(restrictionKey + userHandle.getIdentifier(), enforcers); } }