Loading core/java/android/app/admin/DevicePolicyManager.java +10 −5 Original line number Diff line number Diff line Loading @@ -2358,18 +2358,23 @@ public class DevicePolicyManager { * <p>The calling device admin must be a device or profile owner. If it is not, * a {@link SecurityException} will be thrown. * * <p>The calling device admin can verify the value it has set by calling * {@link #getRequiredStrongAuthTimeout(ComponentName)} and passing in its instance. * * <p>This method can be called on the {@link DevicePolicyManager} instance returned by * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent * profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param timeoutMs The new timeout, after which the user will have to unlock with strong * authentication method. If the timeout is lower than 1 hour (minimum) or higher than * 72 hours (default and maximum) an {@link IllegalArgumentException} is thrown. * authentication method. A value of 0 means the admin is not participating in * controlling the timeout. * The minimum and maximum timeouts are platform-defined and are typically 1 hour and * 72 hours, respectively. Though discouraged, the admin may choose to require strong * auth at all times using {@link #KEYGUARD_DISABLE_FINGERPRINT} and/or * {@link #KEYGUARD_DISABLE_TRUST_AGENTS}. * * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws IllegalArgumentException if the timeout is lower than 1 hour (minimum) or higher than * 72 hours (default and maximum) * * @hide */ Loading @@ -2395,7 +2400,7 @@ public class DevicePolicyManager { * * @param admin The name of the admin component to check, or {@code null} to aggregate * accross all participating admins. * @return The timeout or default timeout if not configured * @return The timeout or 0 if not configured for the provided admin. * * @hide */ Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +16 −11 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0; long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK; long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; long strongAuthUnlockTimeout = 0; // admin doesn't participate by default static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0; int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE; Loading Loading @@ -4266,10 +4266,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkArgument(timeoutMs >= MINIMUM_STRONG_AUTH_TIMEOUT_MS, "Timeout must not be lower than the minimum strong auth timeout."); Preconditions.checkArgument(timeoutMs <= DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS, "Timeout must not be higher than the default strong auth timeout."); Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number."); // timeoutMs with value 0 means that the admin doesn't participate // timeoutMs is clamped to the interval in case the internal constants change in the future if (timeoutMs != 0 && timeoutMs < MINIMUM_STRONG_AUTH_TIMEOUT_MS) { timeoutMs = MINIMUM_STRONG_AUTH_TIMEOUT_MS; } if (timeoutMs > DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) { timeoutMs = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; } final int userHandle = mInjector.userHandleGetCallingUserId(); synchronized (this) { Loading @@ -4285,7 +4290,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * Return a single admin's strong auth unlock timeout or minimum value (strictest) of all * admins if who is null. * Returns default timeout if not configured. * Returns 0 if not configured for the provided admin. */ @Override public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) { Loading @@ -4296,9 +4301,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent); return admin != null ? Math.max(admin.strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS) : DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; return admin != null ? admin.strongAuthUnlockTimeout : 0; } // Return the strictest policy across all participating admins. Loading @@ -4306,8 +4309,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; for (int i = 0; i < admins.size(); i++) { strongAuthUnlockTimeout = Math.min(admins.get(i).strongAuthUnlockTimeout, strongAuthUnlockTimeout); final long timeout = admins.get(i).strongAuthUnlockTimeout; if (timeout != 0) { // take only participating admins into account strongAuthUnlockTimeout = Math.min(timeout, strongAuthUnlockTimeout); } } return Math.max(strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS); } Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -1909,6 +1909,61 @@ public class DevicePolicyManagerTest extends DpmTestBase { verifyScreenTimeoutCall(Integer.MAX_VALUE, false); } public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = 1 * 60 * 60 * 1000; // 1h final long ONE_MINUTE = 60 * 1000; // aggregation should be the default if unset by any admin assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // admin not participating by default assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); //clamping from the top dpm.setRequiredStrongAuthTimeout(admin1, DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // 0 means default dpm.setRequiredStrongAuthTimeout(admin1, 0); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // clamping from the bottom dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS); assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS); // value within range dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); // reset to default dpm.setRequiredStrongAuthTimeout(admin1, 0); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // negative value try { dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE); fail("Didn't throw IllegalArgumentException"); } catch (IllegalArgumentException iae) { } } private void verifyScreenTimeoutCall(Integer expectedTimeout, boolean shouldStayOnWhilePluggedInBeCleared) { if (expectedTimeout == null) { Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +10 −5 Original line number Diff line number Diff line Loading @@ -2358,18 +2358,23 @@ public class DevicePolicyManager { * <p>The calling device admin must be a device or profile owner. If it is not, * a {@link SecurityException} will be thrown. * * <p>The calling device admin can verify the value it has set by calling * {@link #getRequiredStrongAuthTimeout(ComponentName)} and passing in its instance. * * <p>This method can be called on the {@link DevicePolicyManager} instance returned by * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent * profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param timeoutMs The new timeout, after which the user will have to unlock with strong * authentication method. If the timeout is lower than 1 hour (minimum) or higher than * 72 hours (default and maximum) an {@link IllegalArgumentException} is thrown. * authentication method. A value of 0 means the admin is not participating in * controlling the timeout. * The minimum and maximum timeouts are platform-defined and are typically 1 hour and * 72 hours, respectively. Though discouraged, the admin may choose to require strong * auth at all times using {@link #KEYGUARD_DISABLE_FINGERPRINT} and/or * {@link #KEYGUARD_DISABLE_TRUST_AGENTS}. * * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws IllegalArgumentException if the timeout is lower than 1 hour (minimum) or higher than * 72 hours (default and maximum) * * @hide */ Loading @@ -2395,7 +2400,7 @@ public class DevicePolicyManager { * * @param admin The name of the admin component to check, or {@code null} to aggregate * accross all participating admins. * @return The timeout or default timeout if not configured * @return The timeout or 0 if not configured for the provided admin. * * @hide */ Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +16 −11 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0; long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK; long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; long strongAuthUnlockTimeout = 0; // admin doesn't participate by default static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0; int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE; Loading Loading @@ -4266,10 +4266,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkArgument(timeoutMs >= MINIMUM_STRONG_AUTH_TIMEOUT_MS, "Timeout must not be lower than the minimum strong auth timeout."); Preconditions.checkArgument(timeoutMs <= DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS, "Timeout must not be higher than the default strong auth timeout."); Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number."); // timeoutMs with value 0 means that the admin doesn't participate // timeoutMs is clamped to the interval in case the internal constants change in the future if (timeoutMs != 0 && timeoutMs < MINIMUM_STRONG_AUTH_TIMEOUT_MS) { timeoutMs = MINIMUM_STRONG_AUTH_TIMEOUT_MS; } if (timeoutMs > DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) { timeoutMs = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; } final int userHandle = mInjector.userHandleGetCallingUserId(); synchronized (this) { Loading @@ -4285,7 +4290,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * Return a single admin's strong auth unlock timeout or minimum value (strictest) of all * admins if who is null. * Returns default timeout if not configured. * Returns 0 if not configured for the provided admin. */ @Override public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) { Loading @@ -4296,9 +4301,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent); return admin != null ? Math.max(admin.strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS) : DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; return admin != null ? admin.strongAuthUnlockTimeout : 0; } // Return the strictest policy across all participating admins. Loading @@ -4306,8 +4309,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long strongAuthUnlockTimeout = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; for (int i = 0; i < admins.size(); i++) { strongAuthUnlockTimeout = Math.min(admins.get(i).strongAuthUnlockTimeout, strongAuthUnlockTimeout); final long timeout = admins.get(i).strongAuthUnlockTimeout; if (timeout != 0) { // take only participating admins into account strongAuthUnlockTimeout = Math.min(timeout, strongAuthUnlockTimeout); } } return Math.max(strongAuthUnlockTimeout, MINIMUM_STRONG_AUTH_TIMEOUT_MS); } Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -1909,6 +1909,61 @@ public class DevicePolicyManagerTest extends DpmTestBase { verifyScreenTimeoutCall(Integer.MAX_VALUE, false); } public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = 1 * 60 * 60 * 1000; // 1h final long ONE_MINUTE = 60 * 1000; // aggregation should be the default if unset by any admin assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // admin not participating by default assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); //clamping from the top dpm.setRequiredStrongAuthTimeout(admin1, DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // 0 means default dpm.setRequiredStrongAuthTimeout(admin1, 0); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // clamping from the bottom dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS); assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS); // value within range dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); // reset to default dpm.setRequiredStrongAuthTimeout(admin1, 0); assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); assertEquals(dpm.getRequiredStrongAuthTimeout(null), DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); // negative value try { dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE); fail("Didn't throw IllegalArgumentException"); } catch (IllegalArgumentException iae) { } } private void verifyScreenTimeoutCall(Integer expectedTimeout, boolean shouldStayOnWhilePluggedInBeCleared) { if (expectedTimeout == null) { Loading