Allow FP authentication while screensaver (not AOD) is on

FP authentication should be allowed whenever the screen saver is showing,
even if the device is not locked yet.

Fixes: 64537131

Test: 1) Disable AOD
2) Manually start screen saver from Settings
3) Before device is locked, touch FPS, device unlocks and wakes

Test: Do the same as the first test, but wait for the device to be locked
before touching FPS. Device unlocks and wakes

Test: Do the first two tests again with AOD enabled

Change-Id: Icd93a2e73d581e61b1c158b16de243722bd5680c
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index c596398..d95402c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -50,6 +50,7 @@
 import android.os.BatteryManager;
 import android.os.CancellationSignal;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.Message;
 import android.os.RemoteException;
@@ -58,6 +59,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -67,8 +70,6 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
-import com.google.android.collect.Lists;
-
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.PhoneConstants;
@@ -77,6 +78,8 @@
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 
+import com.google.android.collect.Lists;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -217,6 +220,8 @@
     private UserManager mUserManager;
     private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
     private LockPatternUtils mLockPatternUtils;
+    private final IDreamManager mDreamManager;
+    private boolean mIsDreaming;
 
     /**
      * Short delay before restarting fingerprint authentication after a successful try
@@ -458,6 +463,26 @@
         updateFingerprintListeningState();
     }
 
+    /**
+     * @return a cached version of DreamManager.isDreaming()
+     */
+    public boolean isDreaming() {
+        return mIsDreaming;
+    }
+
+    /**
+     * If the device is dreaming, awakens the device
+     */
+    public void awakenFromDream() {
+        if (mIsDreaming && mDreamManager != null) {
+            try {
+                mDreamManager.awaken();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to awaken from dream");
+            }
+        }
+    }
+
     private void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
         mUserFingerprintAuthenticated.put(userId, true);
@@ -1037,11 +1062,11 @@
 
     private void handleDreamingStateChanged(int dreamStart) {
         final int count = mCallbacks.size();
-        boolean showingDream = dreamStart == 1;
+        mIsDreaming = dreamStart == 1;
         for (int i = 0; i < count; i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
-                cb.onDreamingStateChanged(showingDream);
+                cb.onDreamingStateChanged(mIsDreaming);
             }
         }
     }
@@ -1146,6 +1171,9 @@
         mLockPatternUtils = new LockPatternUtils(context);
         mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
 
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.getService(DreamService.DREAM_SERVICE));
+
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
             mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
         }
@@ -1183,7 +1211,7 @@
     private boolean shouldListenForFingerprint() {
         return (mKeyguardIsVisible || !mDeviceInteractive ||
                 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
-                shouldListenForFingerprintAssistant())
+                shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
                 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
                 && !mKeyguardGoingAway;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 316d229..00cb532 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -85,6 +85,11 @@
     public static final int MODE_DISMISS_BOUNCER = 6;
 
     /**
+     * Mode in which fingerprint wakes and unlocks the device from a dream.
+     */
+    public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 7;
+
+    /**
      * How much faster we collapse the lockscreen when authenticating with fingerprint.
      */
     private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
@@ -230,16 +235,19 @@
                 }
                 Trace.endSection();
                 break;
+            case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
             case MODE_WAKE_AND_UNLOCK_PULSING:
             case MODE_WAKE_AND_UNLOCK:
                 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
                     mStatusBar.updateMediaMetaData(false /* metaDataChanged */,
                             true /* allowEnterAnimation */);
-                } else {
+                } else if (mMode == MODE_WAKE_AND_UNLOCK){
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
-
                     mDozeScrimController.abortDoze();
+                } else {
+                    Trace.beginSection("MODE_WAKE_AND_UNLOCK_FROM_DREAM");
+                    mUpdateMonitor.awakenFromDream();
                 }
                 mStatusBarWindowManager.setStatusBarFocusable(false);
                 mKeyguardViewMediator.onWakeAndUnlocking();
@@ -299,6 +307,7 @@
 
     private int calculateMode() {
         boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed();
+        boolean deviceDreaming = mUpdateMonitor.isDreaming();
 
         if (!mUpdateMonitor.isDeviceInteractive()) {
             if (!mStatusBarKeyguardViewManager.isShowing()) {
@@ -311,6 +320,9 @@
                 return MODE_SHOW_BOUNCER;
             }
         }
+        if (unlockingAllowed && deviceDreaming) {
+            return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
+        }
         if (mStatusBarKeyguardViewManager.isShowing()) {
             if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
                 return MODE_DISMISS_BOUNCER;