Merge "Refresh strong auth alarm when admin changes policy" into rvc-dev am: bc7d9bdd5a am: 0a371c7612

Change-Id: I718963ae503b36e55175ab3212ab43f94b9bd652
This commit is contained in:
Rubin Xu
2020-05-01 10:45:16 +00:00
committed by Automerger Merge Worker
5 changed files with 111 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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));
}
}
}

View File

@@ -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);