Merge "Refresh strong auth alarm when admin changes policy" into rvc-dev am: bc7d9bdd5a am: 0a371c7612 am: 571806a405
Change-Id: I465e2f199f1638c33fa0ffcd9549df05581f08e3
This commit is contained in:
@@ -107,4 +107,10 @@ public abstract class LockSettingsInternal {
|
||||
* @return true if the arming worked
|
||||
*/
|
||||
public abstract boolean armRebootEscrow();
|
||||
|
||||
|
||||
/**
|
||||
* Refreshes pending strong auth timeout with the latest admin requirement set by device policy.
|
||||
*/
|
||||
public abstract void refreshStrongAuthTimeout(int userId);
|
||||
}
|
||||
|
||||
@@ -3441,6 +3441,11 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
public boolean armRebootEscrow() {
|
||||
return mRebootEscrowManager.armRebootEscrowIfNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshStrongAuthTimeout(int userId) {
|
||||
mStrongAuth.refreshStrongAuthTimeout(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private class RebootEscrowCallbacks implements RebootEscrowManager.Callbacks {
|
||||
|
||||
@@ -58,6 +58,7 @@ public class LockSettingsStrongAuth {
|
||||
private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_TIMEOUT = 7;
|
||||
private static final int MSG_STRONG_BIOMETRIC_UNLOCK = 8;
|
||||
private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT = 9;
|
||||
private static final int MSG_REFRESH_STRONG_AUTH_TIMEOUT = 10;
|
||||
|
||||
@VisibleForTesting
|
||||
protected static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
|
||||
@@ -143,6 +144,15 @@ public class LockSettingsStrongAuth {
|
||||
public long getNextAlarmTimeMs(long timeout) {
|
||||
return SystemClock.elapsedRealtime() + timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps around {@link SystemClock#elapsedRealtime}, which returns the number of
|
||||
* milliseconds since boot, including time spent in sleep.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public long getElapsedRealtimeMs() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||
@@ -231,22 +241,33 @@ public class LockSettingsStrongAuth {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleScheduleStrongAuthTimeout(int userId) {
|
||||
/**
|
||||
* Re-schedule the strong auth timeout alarm with latest information on the most recent
|
||||
* successful strong auth time and strong auth timeout from device policy.
|
||||
*/
|
||||
private void rescheduleStrongAuthTimeoutAlarm(long strongAuthTime, int userId) {
|
||||
final DevicePolicyManager dpm =
|
||||
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
long nextAlarmTime =
|
||||
mInjector.getNextAlarmTimeMs(dpm.getRequiredStrongAuthTimeout(null, userId));
|
||||
// cancel current alarm listener for the user (if there was one)
|
||||
StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
|
||||
if (alarm != null) {
|
||||
mAlarmManager.cancel(alarm);
|
||||
alarm.setLatestStrongAuthTime(strongAuthTime);
|
||||
} else {
|
||||
alarm = new StrongAuthTimeoutAlarmListener(userId);
|
||||
alarm = new StrongAuthTimeoutAlarmListener(strongAuthTime, userId);
|
||||
mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
|
||||
}
|
||||
// AlarmManager.set() correctly handles the case where nextAlarmTime has already been in
|
||||
// the past (by firing the listener straight away), so nothing special for us to do here.
|
||||
long nextAlarmTime = strongAuthTime + dpm.getRequiredStrongAuthTimeout(null, userId);
|
||||
|
||||
// schedule a new alarm listener for the user
|
||||
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
|
||||
STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler);
|
||||
}
|
||||
|
||||
private void handleScheduleStrongAuthTimeout(int userId) {
|
||||
rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId);
|
||||
|
||||
// cancel current non-strong biometric alarm listener for the user (if there was one)
|
||||
cancelNonStrongBiometricAlarmListener(userId);
|
||||
@@ -256,6 +277,13 @@ public class LockSettingsStrongAuth {
|
||||
setIsNonStrongBiometricAllowed(true, userId);
|
||||
}
|
||||
|
||||
private void handleRefreshStrongAuthTimeout(int userId) {
|
||||
StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
|
||||
if (alarm != null) {
|
||||
rescheduleStrongAuthTimeoutAlarm(alarm.getLatestStrongAuthTime(), userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleScheduleNonStrongBiometricTimeout(int userId) {
|
||||
if (DEBUG) Slog.d(TAG, "handleScheduleNonStrongBiometricTimeout for userId=" + userId);
|
||||
long nextAlarmTime = mInjector.getNextAlarmTimeMs(DEFAULT_NON_STRONG_BIOMETRIC_TIMEOUT_MS);
|
||||
@@ -455,6 +483,13 @@ public class LockSettingsStrongAuth {
|
||||
mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes pending strong auth timeout with the latest admin requirement set by device policy.
|
||||
*/
|
||||
public void refreshStrongAuthTimeout(int userId) {
|
||||
mHandler.obtainMessage(MSG_REFRESH_STRONG_AUTH_TIMEOUT, userId, 0).sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report successful unlocking with biometric
|
||||
*/
|
||||
@@ -489,12 +524,30 @@ public class LockSettingsStrongAuth {
|
||||
@VisibleForTesting
|
||||
protected class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
|
||||
|
||||
private long mLatestStrongAuthTime;
|
||||
private final int mUserId;
|
||||
|
||||
public StrongAuthTimeoutAlarmListener(int userId) {
|
||||
public StrongAuthTimeoutAlarmListener(long latestStrongAuthTime, int userId) {
|
||||
mLatestStrongAuthTime = latestStrongAuthTime;
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the most recent time when a successful strong auth happened, in number of
|
||||
* milliseconds.
|
||||
*/
|
||||
public void setLatestStrongAuthTime(long strongAuthTime) {
|
||||
mLatestStrongAuthTime = strongAuthTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most recent time when a successful strong auth happened, in number of
|
||||
* milliseconds.
|
||||
*/
|
||||
public long getLatestStrongAuthTime() {
|
||||
return mLatestStrongAuthTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAlarm() {
|
||||
requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
|
||||
@@ -558,6 +611,9 @@ public class LockSettingsStrongAuth {
|
||||
case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
|
||||
handleScheduleStrongAuthTimeout(msg.arg1);
|
||||
break;
|
||||
case MSG_REFRESH_STRONG_AUTH_TIMEOUT:
|
||||
handleRefreshStrongAuthTimeout(msg.arg1);
|
||||
break;
|
||||
case MSG_NO_LONGER_REQUIRE_STRONG_AUTH:
|
||||
handleNoLongerRequireStrongAuth(msg.arg1, msg.arg2);
|
||||
break;
|
||||
|
||||
@@ -5904,12 +5904,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
}
|
||||
|
||||
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||
boolean changed = false;
|
||||
synchronized (getLockObject()) {
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
|
||||
if (ap.strongAuthUnlockTimeout != timeoutMs) {
|
||||
ap.strongAuthUnlockTimeout = timeoutMs;
|
||||
saveSettingsLocked(userHandle);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
mLockSettingsInternal.refreshStrongAuthTimeout(userHandle);
|
||||
// Refreshes the parent if profile has unified challenge, since the timeout would
|
||||
// also affect the parent user in this case.
|
||||
if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) {
|
||||
mLockSettingsInternal.refreshStrongAuthTimeout(getProfileParentId(userHandle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static com.android.server.locksettings.LockSettingsStrongAuth.NON_STRONG_
|
||||
import static com.android.server.locksettings.LockSettingsStrongAuth.NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG;
|
||||
import static com.android.server.locksettings.LockSettingsStrongAuth.STRONG_AUTH_TIMEOUT_ALARM_TAG;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
@@ -163,9 +164,11 @@ public class LockSettingsStrongAuthTest {
|
||||
|
||||
@Test
|
||||
public void testReportSuccessfulStrongAuthUnlock_schedulePrimaryAuthTimeout() {
|
||||
final long nextAlarmTime = 1000;
|
||||
when(mInjector.getNextAlarmTimeMs(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)))
|
||||
.thenReturn(nextAlarmTime);
|
||||
final long currentTime = 1000;
|
||||
final long timeout = 1000;
|
||||
final long nextAlarmTime = currentTime + timeout;
|
||||
when(mInjector.getElapsedRealtimeMs()).thenReturn(currentTime);
|
||||
when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(timeout);
|
||||
mStrongAuth.reportSuccessfulStrongAuthUnlock(PRIMARY_USER_ID);
|
||||
|
||||
waitForIdle();
|
||||
@@ -177,6 +180,29 @@ public class LockSettingsStrongAuthTest {
|
||||
verifyAlarm(nextAlarmTime, STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReportSuccessfulStrongAuthUnlock_testRefreshStrongAuthTimeout() {
|
||||
final long currentTime = 1000;
|
||||
final long oldTimeout = 5000;
|
||||
final long nextAlarmTime = currentTime + oldTimeout;
|
||||
when(mInjector.getElapsedRealtimeMs()).thenReturn(currentTime);
|
||||
when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(oldTimeout);
|
||||
mStrongAuth.reportSuccessfulStrongAuthUnlock(PRIMARY_USER_ID);
|
||||
waitForIdle();
|
||||
|
||||
StrongAuthTimeoutAlarmListener alarm =
|
||||
mStrongAuth.mStrongAuthTimeoutAlarmListenerForUser.get(PRIMARY_USER_ID);
|
||||
assertEquals(currentTime, alarm.getLatestStrongAuthTime());
|
||||
verifyAlarm(nextAlarmTime, STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm);
|
||||
|
||||
final long newTimeout = 3000;
|
||||
when(mDPM.getRequiredStrongAuthTimeout(null, PRIMARY_USER_ID)).thenReturn(newTimeout);
|
||||
mStrongAuth.refreshStrongAuthTimeout(PRIMARY_USER_ID);
|
||||
waitForIdle();
|
||||
verify(mAlarmManager).cancel(alarm);
|
||||
verifyAlarm(currentTime + newTimeout, STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReportSuccessfulStrongAuthUnlock_cancelAlarmsAndAllowNonStrongBio() {
|
||||
setupAlarms(PRIMARY_USER_ID);
|
||||
|
||||
Reference in New Issue
Block a user