Make activity manager sleep top activity when dreaming.

Added the concept of a sleep token to represent a demand to sleep.
We grab this token whenever a dream window is visible.

This change also deletes a special condition in shouldSleepLocked()
which would tend to keep activities running when the lock screen
was shown unless they had previously been sleeping.  I believe this
condition is no longer necessary and the policy is much simpler
without it.  Let's see if anything breaks.

NOTE: This can currently only be used within the system server process
but it might make sense to move it to IActivityManager (guarded by
DEVICE_POWER permission) so that keyguard can use it.  If we added
a callback on release to inform the client that the underlying activity
has finished drawing then we could untangle a bunch of keyguard
specific logic.

Bug: 18866521
Change-Id: I84b2118f5b990a71a1647d1cee536ad3d99f3a24
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 936840a..fbacd75 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -17,6 +17,8 @@
 package com.android.server.policy;
 
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
@@ -251,6 +253,7 @@
     WindowManagerFuncs mWindowManagerFuncs;
     WindowManagerInternal mWindowManagerInternal;
     PowerManager mPowerManager;
+    ActivityManagerInternal mActivityManagerInternal;
     DreamManagerInternal mDreamManagerInternal;
     IStatusBarService mStatusBarService;
     boolean mPreloadedRecentApps;
@@ -492,6 +495,8 @@
     boolean mShowingLockscreen;
     boolean mShowingDream;
     boolean mDreamingLockscreen;
+    boolean mDreamingSleepTokenNeeded;
+    SleepToken mDreamingSleepToken;
     boolean mKeyguardSecure;
     boolean mKeyguardSecureIncludingHidden;
     volatile boolean mKeyguardOccluded;
@@ -598,6 +603,7 @@
     private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
     private static final int MSG_POWER_DELAYED_PRESS = 13;
     private static final int MSG_POWER_LONG_PRESS = 14;
+    private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15;
 
     private class PolicyHandler extends Handler {
         @Override
@@ -646,6 +652,9 @@
                 case MSG_POWER_LONG_PRESS:
                     powerLongPress();
                     break;
+                case MSG_UPDATE_DREAMING_SLEEP_TOKEN:
+                    updateDreamingSleepToken(msg.arg1 != 0);
+                    break;
             }
         }
     }
@@ -1219,6 +1228,7 @@
         mWindowManager = windowManager;
         mWindowManagerFuncs = windowManagerFuncs;
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
 
         // Init display burn-in protection
@@ -4235,6 +4245,15 @@
         // while the dream is showing.
         if (!mShowingDream) {
             mDreamingLockscreen = mShowingLockscreen;
+            if (mDreamingSleepTokenNeeded) {
+                mDreamingSleepTokenNeeded = false;
+                mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget();
+            }
+        } else {
+            if (!mDreamingSleepTokenNeeded) {
+                mDreamingSleepTokenNeeded = true;
+                mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget();
+            }
         }
 
         if (mStatusBar != null) {
@@ -5847,6 +5866,18 @@
         }
     }
 
+    private void updateDreamingSleepToken(boolean acquire) {
+        if (acquire) {
+            if (mDreamingSleepToken == null) {
+                mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream");
+            }
+        } else {
+            if (mDreamingSleepToken != null) {
+                mDreamingSleepToken.release();
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public void enableScreenAfterBoot() {
@@ -6483,7 +6514,8 @@
                 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
         pw.print(prefix); pw.print("mShowingLockscreen="); pw.print(mShowingLockscreen);
                 pw.print(" mShowingDream="); pw.print(mShowingDream);
-                pw.print(" mDreamingLockscreen="); pw.println(mDreamingLockscreen);
+                pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
+                pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
         if (mLastInputMethodWindow != null) {
             pw.print(prefix); pw.print("mLastInputMethodWindow=");
                     pw.println(mLastInputMethodWindow);