diff --git a/src/com/android/settings/display/TimeoutPreferenceController.java b/src/com/android/settings/display/TimeoutPreferenceController.java index 6b282ef33b7..3e1d86aa613 100644 --- a/src/com/android/settings/display/TimeoutPreferenceController.java +++ b/src/com/android/settings/display/TimeoutPreferenceController.java @@ -23,6 +23,7 @@ import android.util.Log; import com.android.settings.R; import com.android.settings.TimeoutListPreference; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.core.AbstractPreferenceController; @@ -59,8 +60,7 @@ public class TimeoutPreferenceController extends AbstractPreferenceController im final long currentTimeout = Settings.System.getLong(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE); timeoutListPreference.setValue(String.valueOf(currentTimeout)); - final DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( - Context.DEVICE_POLICY_SERVICE); + final DevicePolicyManagerWrapper dpm = DevicePolicyManagerWrapper.from(mContext); if (dpm != null) { final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext); diff --git a/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java index 3cbde584e13..71c82f004a2 100644 --- a/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java +++ b/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceController.java @@ -32,6 +32,7 @@ import com.android.settings.TimeoutListPreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.overlay.FeatureFactory; import com.android.settings.security.trustagent.TrustAgentManager; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.core.AbstractPreferenceController; @@ -43,14 +44,14 @@ public class LockAfterTimeoutPreferenceController extends AbstractPreferenceCont private final int mUserId; private final LockPatternUtils mLockPatternUtils; private final TrustAgentManager mTrustAgentManager; - private final DevicePolicyManager mDPM; + private final DevicePolicyManagerWrapper mDPM; public LockAfterTimeoutPreferenceController(Context context, int userId, LockPatternUtils lockPatternUtils) { super(context); mUserId = userId; mLockPatternUtils = lockPatternUtils; - mDPM = context.getSystemService(DevicePolicyManager.class); + mDPM = DevicePolicyManagerWrapper.from(context); mTrustAgentManager = FeatureFactory.getFactory(context) .getSecurityFeatureProvider().getTrustAgentManager(); } diff --git a/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java b/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java index 8417219b07c..2de964f2fec 100644 --- a/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java +++ b/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java @@ -18,6 +18,7 @@ package com.android.settings.wrapper; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; @@ -216,4 +217,13 @@ public class DevicePolicyManagerWrapper { public int getDeviceOwnerUserId() { return mDpm.getDeviceOwnerUserId(); } + + /** + * Calls {@code DevicePolicyManager#getMaximumTimeToLock()}. + * + * @see DevicePolicyManager#getMaximumTimeToLock(ComponentName, int) + */ + public long getMaximumTimeToLockForUserAndProfiles(@UserIdInt int userHandle) { + return mDpm.getMaximumTimeToLockForUserAndProfiles(userHandle); + } } diff --git a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java index 480e41fe84f..80a8ade4767 100644 --- a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java @@ -16,38 +16,54 @@ package com.android.settings.display; +import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.content.Context; +import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; -import com.android.settings.testutils.SettingsRobolectricTestRunner; + import com.android.settings.TestConfig; import com.android.settings.TimeoutListPreference; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; -import static com.google.common.truth.Truth.assertThat; +import java.util.Collections; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {ShadowDevicePolicyManagerWrapper.class}) public class TimeoutPreferenceControllerTest { private static final int TIMEOUT = 30; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock private TimeoutListPreference mPreference; - private TimeoutPreferenceController mController; + @Mock + private UserManager mUserManager; + private TimeoutPreferenceController mController; private static final String KEY_SCREEN_TIMEOUT = "screen_timeout"; @Before public void setUp() { MockitoAnnotations.initMocks(this); - + mContext = spy(RuntimeEnvironment.application); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); mController = new TimeoutPreferenceController(mContext, KEY_SCREEN_TIMEOUT); } @@ -59,4 +75,23 @@ public class TimeoutPreferenceControllerTest { SCREEN_OFF_TIMEOUT, 0); assertThat(mode).isEqualTo(TIMEOUT); } + + @Test + public void testUpdateStateNoAdminTimeouts() { + when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.emptyList()); + mController.updateState(mPreference); + verify(mPreference).removeUnusableTimeouts(0, null); + } + + @Test + public void testUpdateStateWithAdminTimeouts() { + final int profileUserId = UserHandle.myUserId(); + final long timeout = 10000; + when(mUserManager.getProfiles(profileUserId)).thenReturn(Collections.emptyList()); + ShadowDevicePolicyManagerWrapper + .setMaximumTimeToLockForUserAndProfiles(profileUserId, timeout); + + mController.updateState(mPreference); + verify(mPreference).removeUnusableTimeouts(timeout, null); + } } diff --git a/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java index 0915060faca..4541e21394d 100644 --- a/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/screenlock/LockAfterTimeoutPreferenceControllerTest.java @@ -16,18 +16,29 @@ package com.android.settings.security.screenlock; +import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; + import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +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.Context; -import android.support.v14.preference.SwitchPreference; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings; +import android.support.v7.preference.Preference; import com.android.internal.widget.LockPatternUtils; import com.android.settings.TestConfig; +import com.android.settings.TimeoutListPreference; import com.android.settings.security.trustagent.TrustAgentManager; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper; import org.junit.Before; import org.junit.Test; @@ -37,8 +48,11 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import java.util.Collections; + @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {ShadowDevicePolicyManagerWrapper.class}) public class LockAfterTimeoutPreferenceControllerTest { private static final int TEST_USER_ID = 0; @@ -47,21 +61,21 @@ public class LockAfterTimeoutPreferenceControllerTest { private LockPatternUtils mLockPatternUtils; @Mock private TrustAgentManager mTrustAgentManager; + @Mock + private TimeoutListPreference mPreference; private Context mContext; private LockAfterTimeoutPreferenceController mController; - private SwitchPreference mPreference; private FakeFeatureFactory mFeatureFactory; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); mFeatureFactory = FakeFeatureFactory.setupForTest(); when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager()) .thenReturn(mTrustAgentManager); - mPreference = new SwitchPreference(mContext); mController = new LockAfterTimeoutPreferenceController( mContext, TEST_USER_ID, mLockPatternUtils); } @@ -100,5 +114,26 @@ public class LockAfterTimeoutPreferenceControllerTest { assertThat(mController.isAvailable()).isFalse(); } + @Test + public void testUpdateStateWithAdminTimeouts() { + final int userId = UserHandle.myUserId(); + final long adminTimeout = 10000; + final int displayTimeout = 5000; + final UserManager um = mock(UserManager.class); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(um); + when(um.getProfiles(userId)).thenReturn(Collections.emptyList()); + + // Fake list of timeout values. + when(mPreference.getEntries()).thenReturn(new CharSequence[] {"10"} ); + when(mPreference.getEntryValues()).thenReturn(new CharSequence[] {"10000"} ); + + Settings.System.putInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, displayTimeout); + ShadowDevicePolicyManagerWrapper + .setMaximumTimeToLockForUserAndProfiles(userId, adminTimeout); + + mController.updateState((Preference) mPreference); + + verify(mPreference).removeUnusableTimeouts(adminTimeout - displayTimeout, null); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManagerWrapper.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManagerWrapper.java index 104cd870359..46a003881a4 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManagerWrapper.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManagerWrapper.java @@ -16,6 +16,7 @@ package com.android.settings.testutils.shadow; +import android.annotation.UserIdInt; import android.content.ComponentName; import com.android.settings.wrapper.DevicePolicyManagerWrapper; @@ -23,6 +24,9 @@ import com.android.settings.wrapper.DevicePolicyManagerWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; +import java.util.HashMap; +import java.util.Map; + /** * Shadow for {@link DevicePolicyManagerWrapper} to allow stubbing hidden methods. */ @@ -30,6 +34,7 @@ import org.robolectric.annotation.Implements; public class ShadowDevicePolicyManagerWrapper { private static ComponentName deviceOComponentName = null; private static int deviceOwnerUserId = -1; + private static final Map profileTimeouts = new HashMap<>(); @Implementation public ComponentName getDeviceOwnerComponentOnAnyUser() { @@ -41,6 +46,11 @@ public class ShadowDevicePolicyManagerWrapper { return deviceOwnerUserId; } + @Implementation + public long getMaximumTimeToLockForUserAndProfiles(@UserIdInt int userHandle) { + return profileTimeouts.getOrDefault(userHandle, 0L); + } + public static void setDeviceOComponentName(ComponentName deviceOComponentName) { ShadowDevicePolicyManagerWrapper.deviceOComponentName = deviceOComponentName; } @@ -48,4 +58,9 @@ public class ShadowDevicePolicyManagerWrapper { public static void setDeviceOwnerUserId(int deviceOwnerUserId) { ShadowDevicePolicyManagerWrapper.deviceOwnerUserId = deviceOwnerUserId; } + + public static void setMaximumTimeToLockForUserAndProfiles( + @UserIdInt int userHandle, Long timeout) { + profileTimeouts.put(userHandle, timeout); + } }