diff options
author | Michal Karpinski <mkarpinski@google.com> | 2017-01-13 18:18:49 +0000 |
---|---|---|
committer | Michal Karpinski <mkarpinski@google.com> | 2017-01-23 14:53:56 +0000 |
commit | e71f583c782a98e977d6a5c450dff856b132e5c6 (patch) | |
tree | 01b800cc4f6a54d4937e174d4e164129bdef638a | |
parent | cc9224c8d4f74987d08cef3c70f88873ae06656d (diff) |
Strong auth timeout refactor
Move timeout scheduling mechanism from KeyguardUpdateMonitor to
LockSettingsStrongAuth.
Move reporting about successful strong auth unlock from
KeyguardUpdateMonitor#reportSuccessfulStrongAuthUnlockAttempt()
to LockSettingsService#doVerifyCredential() - the latter also
covers work challenge strong auth unlocking.
Test: manual with all types of strong and non-strong auth, including work challenge
Bug: 29825955
Change-Id: I38e51b21e3a455b95e3c857e091fe07ee388c7f8
3 files changed, 64 insertions, 43 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 0a7bdbf01e43..80d4a264cac8 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -26,7 +26,6 @@ import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT; import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE; import static android.os.BatteryManager.EXTRA_PLUGGED; import static android.os.BatteryManager.EXTRA_STATUS; -import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT; import android.app.ActivityManager; import android.app.AlarmManager; @@ -106,12 +105,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final String ACTION_FACE_UNLOCK_STOPPED = "com.android.facelock.FACE_UNLOCK_STOPPED"; - private static final String ACTION_STRONG_AUTH_TIMEOUT = - "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT"; - private static final String USER_ID = "com.android.systemui.USER_ID"; - - private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; - // Callback messages private static final int MSG_TIME_UPDATE = 301; private static final int MSG_BATTERY_UPDATE = 302; @@ -203,7 +196,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private boolean mDeviceInteractive; private boolean mScreenOn; private SubscriptionManager mSubscriptionManager; - private AlarmManager mAlarmManager; private List<SubscriptionInfo> mSubscriptionInfo; private TrustManager mTrustManager; private UserManager mUserManager; @@ -588,26 +580,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } public void reportSuccessfulStrongAuthUnlockAttempt() { - scheduleStrongAuthTimeout(); if (mFpm != null) { byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */ mFpm.resetTimeout(token); } } - private void scheduleStrongAuthTimeout() { - final DevicePolicyManager dpm = - (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); - long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, - sCurrentUser); - Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT); - intent.putExtra(USER_ID, sCurrentUser); - PendingIntent sender = PendingIntent.getBroadcast(mContext, - sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT); - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender); - notifyStrongAuthStateChanged(sCurrentUser); - } - private void notifyStrongAuthStateChanged(int userId) { for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); @@ -723,17 +701,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } }; - private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) { - int userId = intent.getIntExtra(USER_ID, -1); - mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, userId); - notifyStrongAuthStateChanged(userId); - } - } - }; - private final FingerprintManager.LockoutResetCallback mLockoutResetCallback = new FingerprintManager.LockoutResetCallback() { @Override @@ -1034,7 +1001,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private KeyguardUpdateMonitor(Context context) { mContext = context; mSubscriptionManager = SubscriptionManager.from(context); - mAlarmManager = context.getSystemService(AlarmManager.class); mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); mStrongAuthTracker = new StrongAuthTracker(context); @@ -1094,10 +1060,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { e.rethrowAsRuntimeException(); } - IntentFilter strongAuthTimeoutFilter = new IntentFilter(); - strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT); - context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter, - PERMISSION_SELF, null /* handler */); mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE); mTrustManager.registerTrustListener(this); mLockPatternUtils = new LockPatternUtils(context); diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 51503c0ac91d..2d40e8eebdb5 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -1196,9 +1196,11 @@ public class LockSettingsService extends ILockSettings.Stub { VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify, hasChallenge, challenge, progressCallback); - if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK - && shouldReEnrollBaseZero) { - setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId); + if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { + mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); + if (shouldReEnrollBaseZero) { + setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId); + } } return response; diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java index 551ceb8c328a..131411060625 100644 --- a/services/core/java/com/android/server/LockSettingsStrongAuth.java +++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java @@ -16,23 +16,30 @@ package com.android.server; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT; + import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils.StrongAuthTracker; +import android.app.AlarmManager; +import android.app.AlarmManager.OnAlarmListener; +import android.app.admin.DevicePolicyManager; import android.app.trust.IStrongAuthTracker; import android.content.Context; +import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; import android.os.Message; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; +import android.util.ArrayMap; import android.util.Slog; import android.util.SparseIntArray; import java.util.ArrayList; -import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; - /** * Keeps track of requests for strong authentication. */ @@ -45,12 +52,22 @@ public class LockSettingsStrongAuth { private static final int MSG_UNREGISTER_TRACKER = 3; private static final int MSG_REMOVE_USER = 4; + private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG = + "LockSettingsStrongAuth.timeoutForUser"; + private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>(); private final SparseIntArray mStrongAuthForUser = new SparseIntArray(); + private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener> + mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>(); private final int mDefaultStrongAuthFlags; + private final Context mContext; + + private AlarmManager mAlarmManager; public LockSettingsStrongAuth(Context context) { + mContext = context; mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context); + mAlarmManager = context.getSystemService(AlarmManager.class); } private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) { @@ -151,6 +168,46 @@ public class LockSettingsStrongAuth { requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId); } + public void reportSuccessfulStrongAuthUnlock(int userId) { + scheduleStrongAuthTimeout(userId); + } + + private void scheduleStrongAuthTimeout(int userId) { + final DevicePolicyManager dpm = + (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); + long when = SystemClock.elapsedRealtime() + 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); + } else { + alarm = new StrongAuthTimeoutAlarmListener(userId); + mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm); + } + // schedule a new alarm listener for the user + final long ident = Binder.clearCallingIdentity(); + try { + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG, + alarm, mHandler); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + private class StrongAuthTimeoutAlarmListener implements OnAlarmListener { + + private final int mUserId; + + public StrongAuthTimeoutAlarmListener(int userId) { + mUserId = userId; + } + + @Override + public void onAlarm() { + requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId); + } + } + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { |