Merge "Strong auth timeout for trust agents"
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index b0bc81b..63b700b 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1432,7 +1432,8 @@
                         STRONG_AUTH_REQUIRED_AFTER_BOOT,
                         STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
                         SOME_AUTH_REQUIRED_AFTER_USER_REQUEST,
-                        STRONG_AUTH_REQUIRED_AFTER_LOCKOUT})
+                        STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
+                        STRONG_AUTH_REQUIRED_AFTER_TIMEOUT})
         @Retention(RetentionPolicy.SOURCE)
         public @interface StrongAuthFlags {}
 
@@ -1463,6 +1464,12 @@
         public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
 
         /**
+         * Strong authentication is required because it hasn't been used for a time required by
+         * a device admin.
+         */
+        public static final int STRONG_AUTH_REQUIRED_AFTER_TIMEOUT = 0x10;
+
+        /**
          * Strong auth flags that do not prevent fingerprint from being accepted as auth.
          *
          * If any other flags are set, fingerprint is disabled.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index cdcc05c..0a7bdbf 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -26,6 +26,7 @@
 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;
@@ -191,8 +192,6 @@
     // Password attempts
     private SparseIntArray mFailedAttempts = new SparseIntArray();
 
-    /** Tracks whether strong authentication hasn't been used since quite some time per user. */
-    private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
     private final StrongAuthTracker mStrongAuthTracker;
 
     private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
@@ -209,6 +208,7 @@
     private TrustManager mTrustManager;
     private UserManager mUserManager;
     private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
+    private LockPatternUtils mLockPatternUtils;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -576,8 +576,7 @@
     }
 
     public boolean isUnlockingWithFingerprintAllowed() {
-        return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
-                && !hasFingerprintUnlockTimedOut(sCurrentUser);
+        return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
     }
 
     public boolean needsSlowUnlockTransition() {
@@ -588,16 +587,7 @@
         return mStrongAuthTracker;
     }
 
-    /**
-     * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
-     *         while and thus can't unlock with fingerprint, false otherwise
-     */
-    public boolean hasFingerprintUnlockTimedOut(int userId) {
-        return !mStrongAuthNotTimedOut.contains(userId);
-    }
-
     public void reportSuccessfulStrongAuthUnlockAttempt() {
-        mStrongAuthNotTimedOut.add(sCurrentUser);
         scheduleStrongAuthTimeout();
         if (mFpm != null) {
             byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
@@ -738,7 +728,7 @@
         public void onReceive(Context context, Intent intent) {
             if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
                 int userId = intent.getIntExtra(USER_ID, -1);
-                mStrongAuthNotTimedOut.remove(userId);
+                mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, userId);
                 notifyStrongAuthStateChanged(userId);
             }
         }
@@ -1110,7 +1100,8 @@
                 PERMISSION_SELF, null /* handler */);
         mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
         mTrustManager.registerTrustListener(this);
-        new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
+        mLockPatternUtils = new LockPatternUtils(context);
+        mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
 
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
             mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
@@ -1839,7 +1830,6 @@
             pw.println("    disabled(DPM)=" + isFingerprintDisabled(userId));
             pw.println("    possible=" + isUnlockWithFingerprintPossible(userId));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
-            pw.println("    timedout=" + hasFingerprintUnlockTimedOut(userId));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 34dc63f..de327bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -20,6 +20,7 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -600,7 +601,7 @@
 
             if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
                 return KeyguardSecurityView.PROMPT_REASON_RESTART;
-            } else if (fingerprint && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
+            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
                 return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
             } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
                 return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;