am 1ac13e02: am 682ed6b6: Merge "resolved conflicts for merge of 694c1d2b to lmp-mr1-dev" into lmp-mr1-dev

* commit '1ac13e0212a770c918d32e6c645682466113632c':
  Support keeping activities resumed while dozing.
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 2a17fa6..d56dc1e 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -23,8 +23,8 @@
  */
 public abstract class ActivityManagerInternal {
     // Called by the power manager.
-    public abstract void goingToSleep();
-    public abstract void wakingUp();
+    public abstract void onWakefulnessChanged(int wakefulness);
+
     public abstract int startIsolatedProcess(String entryPoint, String[] mainArgs,
             String processName, String abiOverride, int uid, Runnable crashHandler);
 }
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 9d78360..6f31768 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -25,6 +25,58 @@
  */
 public abstract class PowerManagerInternal {
     /**
+     * Wakefulness: The device is asleep.  It can only be awoken by a call to wakeUp().
+     * The screen should be off or in the process of being turned off by the display controller.
+     * The device typically passes through the dozing state first.
+     */
+    public static final int WAKEFULNESS_ASLEEP = 0;
+
+    /**
+     * Wakefulness: The device is fully awake.  It can be put to sleep by a call to goToSleep().
+     * When the user activity timeout expires, the device may start dreaming or go to sleep.
+     */
+    public static final int WAKEFULNESS_AWAKE = 1;
+
+    /**
+     * Wakefulness: The device is dreaming.  It can be awoken by a call to wakeUp(),
+     * which ends the dream.  The device goes to sleep when goToSleep() is called, when
+     * the dream ends or when unplugged.
+     * User activity may brighten the screen but does not end the dream.
+     */
+    public static final int WAKEFULNESS_DREAMING = 2;
+
+    /**
+     * Wakefulness: The device is dozing.  It is almost asleep but is allowing a special
+     * low-power "doze" dream to run which keeps the display on but lets the application
+     * processor be suspended.  It can be awoken by a call to wakeUp() which ends the dream.
+     * The device fully goes to sleep if the dream cannot be started or ends on its own.
+     */
+    public static final int WAKEFULNESS_DOZING = 3;
+
+    public static String wakefulnessToString(int wakefulness) {
+        switch (wakefulness) {
+            case WAKEFULNESS_ASLEEP:
+                return "Asleep";
+            case WAKEFULNESS_AWAKE:
+                return "Awake";
+            case WAKEFULNESS_DREAMING:
+                return "Dreaming";
+            case WAKEFULNESS_DOZING:
+                return "Dozing";
+            default:
+                return Integer.toString(wakefulness);
+        }
+    }
+
+    /**
+     * Returns true if the wakefulness state represents an interactive state
+     * as defined by {@link android.os.PowerManager#isInteractive}.
+     */
+    public static boolean isInteractive(int wakefulness) {
+        return wakefulness == WAKEFULNESS_AWAKE || wakefulness == WAKEFULNESS_DREAMING;
+    }
+
+    /**
      * Used by the window manager to override the screen brightness based on the
      * current foreground activity.
      *
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f0fb9e6..40563fe 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -173,6 +173,7 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -958,9 +959,9 @@
     private boolean mRunningVoice = false;
 
     /**
-     * State of external calls telling us if the device is asleep.
+     * State of external calls telling us if the device is awake or asleep.
      */
-    private boolean mWentToSleep = false;
+    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
 
     static final int LOCK_SCREEN_HIDDEN = 0;
     static final int LOCK_SCREEN_LEAVING = 1;
@@ -6061,6 +6062,7 @@
                 mWindowManager.keyguardWaitingForActivityDrawn();
                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
                     mLockScreenShown = LOCK_SCREEN_LEAVING;
+                    updateSleepIfNeededLocked();
                 }
             }
         } finally {
@@ -9925,32 +9927,55 @@
         return mSleeping;
     }
 
-    void goingToSleep() {
+    void onWakefulnessChanged(int wakefulness) {
         synchronized(this) {
-            mWentToSleep = true;
-            goToSleepIfNeededLocked();
+            mWakefulness = wakefulness;
+            updateSleepIfNeededLocked();
         }
     }
 
     void finishRunningVoiceLocked() {
         if (mRunningVoice) {
             mRunningVoice = false;
-            goToSleepIfNeededLocked();
+            updateSleepIfNeededLocked();
         }
     }
 
-    void goToSleepIfNeededLocked() {
-        if (mWentToSleep && !mRunningVoice) {
-            if (!mSleeping) {
-                mSleeping = true;
-                mStackSupervisor.goingToSleepLocked();
+    void updateSleepIfNeededLocked() {
+        if (mSleeping && !shouldSleepLocked()) {
+            mSleeping = false;
+            mStackSupervisor.comeOutOfSleepIfNeededLocked();
+        } else if (!mSleeping && shouldSleepLocked()) {
+            mSleeping = true;
+            mStackSupervisor.goingToSleepLocked();
 
-                // Initialize the wake times of all processes.
-                checkExcessivePowerUsageLocked(false);
-                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
-                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
-            }
+            // Initialize the wake times of all processes.
+            checkExcessivePowerUsageLocked(false);
+            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
+            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
+            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
+        }
+    }
+
+    private boolean shouldSleepLocked() {
+        // Resume applications while running a voice interactor.
+        if (mRunningVoice) {
+            return false;
+        }
+
+        switch (mWakefulness) {
+            case PowerManagerInternal.WAKEFULNESS_AWAKE:
+            case PowerManagerInternal.WAKEFULNESS_DREAMING:
+                // If we're interactive but applications are already paused then defer
+                // resuming them until the lock screen is hidden.
+                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
+            case PowerManagerInternal.WAKEFULNESS_DOZING:
+                // If we're dozing then pause applications whenever the lock screen is shown.
+                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
+            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
+            default:
+                // If we're asleep then pause applications unconditionally.
+                return true;
         }
     }
 
@@ -10016,31 +10041,16 @@
     }
 
     void logLockScreen(String msg) {
-        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
-                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
-                mWentToSleep + " mSleeping=" + mSleeping);
-    }
-
-    void comeOutOfSleepIfNeededLocked() {
-        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
-            if (mSleeping) {
-                mSleeping = false;
-                mStackSupervisor.comeOutOfSleepIfNeededLocked();
-            }
-        }
-    }
-
-    void wakingUp() {
-        synchronized(this) {
-            mWentToSleep = false;
-            comeOutOfSleepIfNeededLocked();
-        }
+        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
+                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
+                + PowerManagerInternal.wakefulnessToString(mWakefulness)
+                + " mSleeping=" + mSleeping);
     }
 
     void startRunningVoiceLocked() {
         if (!mRunningVoice) {
             mRunningVoice = true;
-            comeOutOfSleepIfNeededLocked();
+            updateSleepIfNeededLocked();
         }
     }
 
@@ -10060,7 +10070,7 @@
             try {
                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
-                comeOutOfSleepIfNeededLocked();
+                updateSleepIfNeededLocked();
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -12830,13 +12840,11 @@
             }
         }
         if (dumpPackage == null) {
-            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
-                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
-                        + " mLockScreenShown " + lockScreenShownToString());
-            }
-            if (mShuttingDown || mRunningVoice) {
-                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
-            }
+            pw.println("  mWakefulness="
+                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
+            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
+                    + lockScreenShownToString());
+            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
         }
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                 || mOrigWaitForDebugger) {
@@ -19204,13 +19212,8 @@
 
     private final class LocalService extends ActivityManagerInternal {
         @Override
-        public void goingToSleep() {
-            ActivityManagerService.this.goingToSleep();
-        }
-
-        @Override
-        public void wakingUp() {
-            ActivityManagerService.this.wakingUp();
+        public void onWakefulnessChanged(int wakefulness) {
+            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c8b7205..5a948f9 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1477,7 +1477,7 @@
             mStackSupervisor.inResumeTopActivity = true;
             if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                 mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
-                mService.comeOutOfSleepIfNeededLocked();
+                mService.updateSleepIfNeededLocked();
             }
             result = resumeTopActivityInnerLocked(prev, options);
         } finally {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 94a628d..1349926 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -38,6 +38,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -70,9 +71,9 @@
 
     private static final boolean DEBUG = false;
 
-    private static final int POWER_STATE_UNKNOWN = 0;
-    private static final int POWER_STATE_AWAKE = 1;
-    private static final int POWER_STATE_ASLEEP = 2;
+    private static final int INTERACTIVE_STATE_UNKNOWN = 0;
+    private static final int INTERACTIVE_STATE_AWAKE = 1;
+    private static final int INTERACTIVE_STATE_ASLEEP = 2;
 
     private static final int MSG_USER_ACTIVITY = 1;
     private static final int MSG_BROADCAST = 2;
@@ -92,17 +93,17 @@
     private final Intent mScreenOnIntent;
     private final Intent mScreenOffIntent;
 
-    // The current power state.
-    private int mActualPowerState;
-    private int mLastGoToSleepReason;
+    // The current interactive state.
+    private int mActualInteractiveState;
+    private int mLastReason;
 
     // True if there is a pending transition that needs to be reported.
     private boolean mPendingWakeUpBroadcast;
     private boolean mPendingGoToSleepBroadcast;
 
-    // The currently broadcasted power state.  This reflects what other parts of the
+    // The currently broadcasted interactive state.  This reflects what other parts of the
     // system have observed.
-    private int mBroadcastedPowerState;
+    private int mBroadcastedInteractiveState;
     private boolean mBroadcastInProgress;
     private long mBroadcastStartTime;
 
@@ -236,62 +237,83 @@
     }
 
     /**
-     * Notifies that the device is changing interactive state.
+     * Notifies that the device is changing wakefulness.
      */
-    public void onInteractiveStateChangeStarted(boolean interactive, final int reason) {
+    public void onWakefulnessChangeStarted(int wakefulness, int reason) {
         if (DEBUG) {
-            Slog.d(TAG, "onInteractiveChangeStarted: interactive=" + interactive
+            Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
                     + ", reason=" + reason);
         }
 
+        // We handle interactive state changes once they start so that the system can
+        // set everything up or the user to begin interacting with applications.
+        final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
+        if (interactive) {
+            handleWakefulnessChange(wakefulness, interactive, reason);
+        } else {
+            mLastReason = reason;
+        }
+
+        // Start input as soon as we start waking up or going to sleep.
+        mInputManagerInternal.setInteractive(interactive);
+    }
+
+    /**
+     * Notifies that the device has finished changing wakefulness.
+     */
+    public void onWakefulnessChangeFinished(int wakefulness) {
+        if (DEBUG) {
+            Slog.d(TAG, "onWakefulnessChangeFinished: wakefulness=" + wakefulness);
+        }
+
+        // Handle interactive state changes once they are finished so that the system can
+        // finish pending transitions (such as turning the screen off) before causing
+        // applications to change state visibly.
+        final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
+        if (!interactive) {
+            handleWakefulnessChange(wakefulness, interactive, mLastReason);
+        }
+    }
+
+    private void handleWakefulnessChange(final int wakefulness, boolean interactive,
+            final int reason) {
+        // Tell the activity manager about changes in wakefulness, not just interactivity.
+        // It needs more granularity than other components.
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mActivityManagerInternal.onWakefulnessChanged(wakefulness);
+            }
+        });
+
+        // Handle changes in the overall interactive state.
+        boolean interactiveChanged = false;
         synchronized (mLock) {
+            // Broadcast interactive state changes.
             if (interactive) {
                 // Waking up...
-                if (mActualPowerState != POWER_STATE_AWAKE) {
-                    mActualPowerState = POWER_STATE_AWAKE;
+                interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_AWAKE);
+                if (interactiveChanged) {
+                    mActualInteractiveState = INTERACTIVE_STATE_AWAKE;
                     mPendingWakeUpBroadcast = true;
                     mHandler.post(new Runnable() {
                         @Override
                         public void run() {
                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
                             mPolicy.wakingUp();
-                            mActivityManagerInternal.wakingUp();
                         }
                     });
                     updatePendingBroadcastLocked();
                 }
             } else {
                 // Going to sleep...
-                mLastGoToSleepReason = reason;
-            }
-        }
-
-        mInputManagerInternal.setInteractive(interactive);
-
-        if (interactive) {
-            try {
-                mBatteryStats.noteInteractive(true);
-            } catch (RemoteException ex) { }
-        }
-    }
-
-    /**
-     * Notifies that the device has finished changing interactive state.
-     */
-    public void onInteractiveStateChangeFinished(boolean interactive) {
-        if (DEBUG) {
-            Slog.d(TAG, "onInteractiveChangeFinished");
-        }
-
-        synchronized (mLock) {
-            if (!interactive) {
-                // Finished going to sleep...
                 // This is a good time to make transitions that we don't want the user to see,
                 // such as bringing the key guard to focus.  There's no guarantee for this,
                 // however because the user could turn the device on again at any time.
                 // Some things may need to be protected by other mechanisms that defer screen on.
-                if (mActualPowerState != POWER_STATE_ASLEEP) {
-                    mActualPowerState = POWER_STATE_ASLEEP;
+                interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_ASLEEP);
+                if (interactiveChanged) {
+                    mActualInteractiveState = INTERACTIVE_STATE_ASLEEP;
                     mPendingGoToSleepBroadcast = true;
                     if (mUserActivityPending) {
                         mUserActivityPending = false;
@@ -301,7 +323,7 @@
                         @Override
                         public void run() {
                             int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
-                            switch (mLastGoToSleepReason) {
+                            switch (reason) {
                                 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
                                     why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
                                     break;
@@ -311,7 +333,6 @@
                             }
                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
                             mPolicy.goingToSleep(why);
-                            mActivityManagerInternal.goingToSleep();
                         }
                     });
                     updatePendingBroadcastLocked();
@@ -319,9 +340,10 @@
             }
         }
 
-        if (!interactive) {
+        // Notify battery stats.
+        if (interactiveChanged) {
             try {
-                mBatteryStats.noteInteractive(false);
+                mBatteryStats.noteInteractive(interactive);
             } catch (RemoteException ex) { }
         }
     }
@@ -366,9 +388,9 @@
 
     private void updatePendingBroadcastLocked() {
         if (!mBroadcastInProgress
-                && mActualPowerState != POWER_STATE_UNKNOWN
+                && mActualInteractiveState != INTERACTIVE_STATE_UNKNOWN
                 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
-                        || mActualPowerState != mBroadcastedPowerState)) {
+                        || mActualInteractiveState != mBroadcastedInteractiveState)) {
             mBroadcastInProgress = true;
             mSuspendBlocker.acquire();
             Message msg = mHandler.obtainMessage(MSG_BROADCAST);
@@ -396,16 +418,16 @@
     private void sendNextBroadcast() {
         final int powerState;
         synchronized (mLock) {
-            if (mBroadcastedPowerState == POWER_STATE_UNKNOWN) {
+            if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
                 // Broadcasted power state is unknown.  Send wake up.
                 mPendingWakeUpBroadcast = false;
-                mBroadcastedPowerState = POWER_STATE_AWAKE;
-            } else if (mBroadcastedPowerState == POWER_STATE_AWAKE) {
+                mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
+            } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
                 // Broadcasted power state is awake.  Send asleep if needed.
                 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
-                        || mActualPowerState == POWER_STATE_ASLEEP) {
+                        || mActualInteractiveState == INTERACTIVE_STATE_ASLEEP) {
                     mPendingGoToSleepBroadcast = false;
-                    mBroadcastedPowerState = POWER_STATE_ASLEEP;
+                    mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
                 } else {
                     finishPendingBroadcastLocked();
                     return;
@@ -413,9 +435,9 @@
             } else {
                 // Broadcasted power state is asleep.  Send awake if needed.
                 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
-                        || mActualPowerState == POWER_STATE_AWAKE) {
+                        || mActualInteractiveState == INTERACTIVE_STATE_AWAKE) {
                     mPendingWakeUpBroadcast = false;
-                    mBroadcastedPowerState = POWER_STATE_AWAKE;
+                    mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
                 } else {
                     finishPendingBroadcastLocked();
                     return;
@@ -423,12 +445,12 @@
             }
 
             mBroadcastStartTime = SystemClock.uptimeMillis();
-            powerState = mBroadcastedPowerState;
+            powerState = mBroadcastedInteractiveState;
         }
 
         EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
 
-        if (powerState == POWER_STATE_AWAKE) {
+        if (powerState == INTERACTIVE_STATE_AWAKE) {
             sendWakeUpBroadcast();
         } else {
             sendGoToSleepBroadcast();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4d8b98f..4d1ab4c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -61,7 +61,6 @@
 import android.provider.Settings;
 import android.service.dreams.DreamManagerInternal;
 import android.util.EventLog;
-import android.util.Log;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.view.Display;
@@ -73,6 +72,11 @@
 
 import libcore.util.Objects;
 
+import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
+import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
+
 /**
  * The power manager service is responsible for coordinating power management
  * functions on the device.
@@ -116,24 +120,6 @@
     // Dirty bit: brightness boost changed
     private static final int DIRTY_SCREEN_BRIGHTNESS_BOOST = 1 << 11;
 
-    // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
-    // The screen should be off or in the process of being turned off by the display controller.
-    // The device typically passes through the dozing state first.
-    private static final int WAKEFULNESS_ASLEEP = 0;
-    // Wakefulness: The device is fully awake.  It can be put to sleep by a call to goToSleep().
-    // When the user activity timeout expires, the device may start dreaming or go to sleep.
-    private static final int WAKEFULNESS_AWAKE = 1;
-    // Wakefulness: The device is dreaming.  It can be awoken by a call to wakeUp(),
-    // which ends the dream.  The device goes to sleep when goToSleep() is called, when
-    // the dream ends or when unplugged.
-    // User activity may brighten the screen but does not end the dream.
-    private static final int WAKEFULNESS_DREAMING = 2;
-    // Wakefulness: The device is dozing.  It is almost asleep but is allowing a special
-    // low-power "doze" dream to run which keeps the display on but lets the application
-    // processor be suspended.  It can be awoken by a call to wakeUp() which ends the dream.
-    // The device fully goes to sleep if the dream cannot be started or ends on its own.
-    private static final int WAKEFULNESS_DOZING = 3;
-
     // Summarizes the state of all active wakelocks.
     private static final int WAKE_LOCK_CPU = 1 << 0;
     private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
@@ -187,6 +173,7 @@
     // Indicates whether the device is awake or asleep or somewhere in between.
     // This is distinct from the screen power state, which is managed separately.
     private int mWakefulness;
+    private boolean mWakefulnessChanging;
 
     // True if the sandman has just been summoned for the first time since entering the
     // dreaming or dozing state.  Indicates whether a new dream should begin.
@@ -205,10 +192,6 @@
     // A bitfield that summarizes the state of all active wakelocks.
     private int mWakeLockSummary;
 
-    // True if the device is in an interactive state.
-    private boolean mInteractive;
-    private boolean mInteractiveChanging;
-
     // If true, instructs the display controller to wait for the proximity sensor to
     // go negative before turning the screen on.
     private boolean mRequestWaitForNegativeProximity;
@@ -467,7 +450,6 @@
             mHalInteractiveModeEnabled = true;
 
             mWakefulness = WAKEFULNESS_AWAKE;
-            mInteractive = true;
 
             nativeInit();
             nativeSetAutoSuspend(false);
@@ -1047,9 +1029,7 @@
             }
 
             mLastWakeTime = eventTime;
-            mDirty |= DIRTY_WAKEFULNESS;
-            mWakefulness = WAKEFULNESS_AWAKE;
-            setInteractiveStateLocked(true, 0);
+            setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
 
             userActivityNoUpdateLocked(
                     eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
@@ -1109,10 +1089,8 @@
             }
 
             mLastSleepTime = eventTime;
-            mDirty |= DIRTY_WAKEFULNESS;
-            mWakefulness = WAKEFULNESS_DOZING;
             mSandmanSummoned = true;
-            setInteractiveStateLocked(false, reason);
+            setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
 
             // Report the number of wake locks that will be cleared by going to sleep.
             int numWakeLocksCleared = 0;
@@ -1161,10 +1139,8 @@
         try {
             Slog.i(TAG, "Nap time (uid " + uid +")...");
 
-            mDirty |= DIRTY_WAKEFULNESS;
-            mWakefulness = WAKEFULNESS_DREAMING;
             mSandmanSummoned = true;
-            setInteractiveStateLocked(true, 0);
+            setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
@@ -1187,29 +1163,28 @@
         try {
             Slog.i(TAG, "Sleeping (uid " + uid +")...");
 
-            mDirty |= DIRTY_WAKEFULNESS;
-            mWakefulness = WAKEFULNESS_ASLEEP;
-            setInteractiveStateLocked(false, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+            setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
         }
         return true;
     }
 
-    private void setInteractiveStateLocked(boolean interactive, int reason) {
-        if (mInteractive != interactive) {
-            finishInteractiveStateChangeLocked();
+    private void setWakefulnessLocked(int wakefulness, int reason) {
+        if (mWakefulness != wakefulness) {
+            finishWakefulnessChangeLocked();
 
-            mInteractive = interactive;
-            mInteractiveChanging = true;
-            mNotifier.onInteractiveStateChangeStarted(interactive, reason);
+            mWakefulness = wakefulness;
+            mWakefulnessChanging = true;
+            mDirty |= DIRTY_WAKEFULNESS;
+            mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
         }
     }
 
-    private void finishInteractiveStateChangeLocked() {
-        if (mInteractiveChanging) {
-            mNotifier.onInteractiveStateChangeFinished(mInteractive);
-            mInteractiveChanging = false;
+    private void finishWakefulnessChangeLocked() {
+        if (mWakefulnessChanging) {
+            mNotifier.onWakefulnessChangeFinished(mWakefulness);
+            mWakefulnessChanging = false;
         }
     }
 
@@ -1261,7 +1236,7 @@
 
             // Phase 4: Send notifications, if needed.
             if (mDisplayReady) {
-                finishInteractiveStateChangeLocked();
+                finishWakefulnessChangeLocked();
             }
 
             // Phase 5: Update suspend blocker.
@@ -1450,7 +1425,7 @@
 
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
-                        + wakefulnessToString(mWakefulness)
+                        + PowerManagerInternal.wakefulnessToString(mWakefulness)
                         + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
             }
         }
@@ -1527,7 +1502,7 @@
 
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
-                        + wakefulnessToString(mWakefulness)
+                        + PowerManagerInternal.wakefulnessToString(mWakefulness)
                         + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                         + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
             }
@@ -2150,7 +2125,7 @@
 
     private boolean isInteractiveInternal() {
         synchronized (mLock) {
-            return mInteractive;
+            return PowerManagerInternal.isInteractive(mWakefulness);
         }
     }
 
@@ -2428,8 +2403,8 @@
         synchronized (mLock) {
             pw.println("Power Manager State:");
             pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
-            pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
-            pw.println("  mInteractive=" + mInteractive);
+            pw.println("  mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness));
+            pw.println("  mWakefulnessChanging=" + mWakefulnessChanging);
             pw.println("  mIsPowered=" + mIsPowered);
             pw.println("  mPlugType=" + mPlugType);
             pw.println("  mBatteryLevel=" + mBatteryLevel);
@@ -2564,21 +2539,6 @@
         return suspendBlocker;
     }
 
-    private static String wakefulnessToString(int wakefulness) {
-        switch (wakefulness) {
-            case WAKEFULNESS_ASLEEP:
-                return "Asleep";
-            case WAKEFULNESS_AWAKE:
-                return "Awake";
-            case WAKEFULNESS_DREAMING:
-                return "Dreaming";
-            case WAKEFULNESS_DOZING:
-                return "Dozing";
-            default:
-                return Integer.toString(wakefulness);
-        }
-    }
-
     private static WorkSource copyWorkSource(WorkSource workSource) {
         return workSource != null ? new WorkSource(workSource) : null;
     }