diff --git a/api/current.txt b/api/current.txt
index 6a32efe..9b54814 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16273,6 +16273,7 @@
     method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String);
     method public void reboot(java.lang.String);
     method public void userActivity(long, boolean);
+    method public void wakeUp(long);
     field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
     field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
@@ -18763,7 +18764,7 @@
     field public static final android.net.Uri DEFAULT_NOTIFICATION_URI;
     field public static final android.net.Uri DEFAULT_RINGTONE_URI;
     field public static final deprecated java.lang.String DEVICE_PROVISIONED = "device_provisioned";
-    field public static final java.lang.String DIM_SCREEN = "dim_screen";
+    field public static final deprecated java.lang.String DIM_SCREEN = "dim_screen";
     field public static final java.lang.String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
     field public static final java.lang.String END_BUTTON_BEHAVIOR = "end_button_behavior";
     field public static final java.lang.String FONT_SCALE = "font_scale";
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index e1d6619..deef2a3 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -64,7 +64,7 @@
                             = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
                     try {
                         IBinder lock = new Binder();
-                        pm.acquireWakeLock(PowerManager.FULL_WAKE_LOCK, lock, "svc power", null);
+                        pm.acquireWakeLock(lock, PowerManager.FULL_WAKE_LOCK, "svc power", null);
                         pm.setStayOnSetting(val);
                         pm.releaseWakeLock(lock, 0);
                     }
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index f3a442a..107e980 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -232,6 +232,13 @@
     }
 
     /**
+     * @hide
+     */
+    public static float getDurationScale() {
+        return sDurationScale;
+    }
+
+    /**
      * Creates a new ValueAnimator object. This default constructor is primarily for
      * use internally; the factory methods which take parameters are more generally
      * useful.
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1ef14eb..fd4c304 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -418,7 +418,8 @@
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(POWER_SERVICE);
                     IPowerManager service = IPowerManager.Stub.asInterface(b);
-                    return new PowerManager(service, ctx.mMainThread.getHandler());
+                    return new PowerManager(ctx.getOuterContext(),
+                            service, ctx.mMainThread.getHandler());
                 }});
 
         registerService(SEARCH_SERVICE, new ServiceFetcher() {
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index b892c81..7785368 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -123,6 +123,7 @@
         }
         mQueue = mLooper.mQueue;
         mCallback = null;
+        mAsynchronous = false;
     }
 
     /**
@@ -147,6 +148,7 @@
         }
         mQueue = mLooper.mQueue;
         mCallback = callback;
+        mAsynchronous = false;
     }
 
     /**
@@ -156,6 +158,7 @@
         mLooper = looper;
         mQueue = looper.mQueue;
         mCallback = null;
+        mAsynchronous = false;
     }
 
     /**
@@ -166,6 +169,31 @@
         mLooper = looper;
         mQueue = looper.mQueue;
         mCallback = callback;
+        mAsynchronous = false;
+    }
+
+    /**
+     * Use the provided queue instead of the default one and take a callback
+     * interface in which to handle messages.  Also set whether the handler
+     * should be asynchronous.
+     *
+     * Handlers are synchronous by default unless this constructor is used to make
+     * one that is strictly asynchronous.
+     *
+     * Asynchronous messages represent interrupts or events that do not require global ordering
+     * with represent to synchronous messages.  Asynchronous messages are not subject to
+     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
+     *
+     * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
+     * each {@link Message} that is sent to it or {@link Runnable} that is posted to it.
+     *
+     * @hide
+     */
+    public Handler(Looper looper, Callback callback, boolean async) {
+        mLooper = looper;
+        mQueue = looper.mQueue;
+        mCallback = callback;
+        mAsynchronous = async;
     }
 
     /**
@@ -464,20 +492,15 @@
      *         the looper is quit before the delivery time of the message
      *         occurs then the message will be dropped.
      */
-    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
-    {
-        boolean sent = false;
+    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
         MessageQueue queue = mQueue;
-        if (queue != null) {
-            msg.target = this;
-            sent = queue.enqueueMessage(msg, uptimeMillis);
-        }
-        else {
+        if (queue == null) {
             RuntimeException e = new RuntimeException(
-                this + " sendMessageAtTime() called with no mQueue");
+                    this + " sendMessageAtTime() called with no mQueue");
             Log.w("Looper", e.getMessage(), e);
+            return false;
         }
-        return sent;
+        return enqueueMessage(queue, msg, uptimeMillis);
     }
 
     /**
@@ -492,20 +515,23 @@
      *         message queue.  Returns false on failure, usually because the
      *         looper processing the message queue is exiting.
      */
-    public final boolean sendMessageAtFrontOfQueue(Message msg)
-    {
-        boolean sent = false;
+    public final boolean sendMessageAtFrontOfQueue(Message msg) {
         MessageQueue queue = mQueue;
-        if (queue != null) {
-            msg.target = this;
-            sent = queue.enqueueMessage(msg, 0);
-        }
-        else {
+        if (queue == null) {
             RuntimeException e = new RuntimeException(
                 this + " sendMessageAtTime() called with no mQueue");
             Log.w("Looper", e.getMessage(), e);
+            return false;
         }
-        return sent;
+        return enqueueMessage(queue, msg, 0);
+    }
+
+    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
+        msg.target = this;
+        if (mAsynchronous) {
+            msg.setAsynchronous(true);
+        }
+        return queue.enqueueMessage(msg, uptimeMillis);
     }
 
     /**
@@ -618,5 +644,6 @@
     final MessageQueue mQueue;
     final Looper mLooper;
     final Callback mCallback;
+    final boolean mAsynchronous;
     IMessenger mMessenger;
 }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 270e9be..7aee644 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -23,27 +23,33 @@
 
 interface IPowerManager
 {
-    // WARNING: changes in acquireWakeLock() signature must be reflected in IPowerManager.cpp/h
-    void acquireWakeLock(int flags, IBinder lock, String tag, in WorkSource ws);
-    void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
-    void goToSleep(long time);
-    void goToSleepWithReason(long time, int reason);
-    // WARNING: changes in releaseWakeLock() signature must be reflected in IPowerManager.cpp/h
+    // WARNING: The first two methods must remain the first two methods because their
+    // transaction numbers must not change unless IPowerManager.cpp is also updated.
+    void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws);
     void releaseWakeLock(IBinder lock, int flags);
-    void userActivity(long when, boolean noChangeLights);
-    void userActivityWithForce(long when, boolean noChangeLights, boolean force);
-    void clearUserActivityTimeout(long now, long timeout);
-    void setPokeLock(int pokey, IBinder lock, String tag);
-    int getSupportedWakeLockFlags();
-    void setStayOnSetting(int val);
-    void setMaximumScreenOffTimeount(int timeMs);
-    void preventScreenOn(boolean prevent);
+
+    void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
+    boolean isWakeLockLevelSupported(int level);
+
+    void userActivity(long time, int event, int flags);
+    void wakeUp(long time);
+    void goToSleep(long time, int reason);
+
     boolean isScreenOn();
     void reboot(String reason);
     void crash(String message);
 
-    // sets the brightness of the backlights (screen, keyboard, button) 0-255
-    void setBacklightBrightness(int brightness);
+    void clearUserActivityTimeout(long now, long timeout);
+    void setPokeLock(int pokey, IBinder lock, String tag);
+    void setStayOnSetting(int val);
+    void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
+    void preventScreenOn(boolean prevent);
+
+    // temporarily overrides the screen brightness settings to allow the user to
+    // see the effect of a settings change without applying it immediately
+    void setTemporaryScreenBrightnessSettingOverride(int brightness);
+    void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj);
+
+    // sets the attention light (used by phone app only)
     void setAttentionLight(boolean on, int color);
-    void setAutoBrightnessAdjustment(float adj);
 }
diff --git a/core/java/android/os/LocalPowerManager.java b/core/java/android/os/LocalPowerManager.java
index 09336c7..519315c 100644
--- a/core/java/android/os/LocalPowerManager.java
+++ b/core/java/android/os/LocalPowerManager.java
@@ -18,25 +18,11 @@
 
 /** @hide */
 public interface LocalPowerManager {
+    // FIXME: Replace poke locks with something else.
+
     public static final int POKE_LOCK_IGNORE_TOUCH_EVENTS = 0x1;
 
     public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2;
     public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4;
     public static final int POKE_LOCK_TIMEOUT_MASK = 0x6;
-
-    void goToSleep(long time);
-    
-    // notify power manager when keyboard is opened/closed
-    void setKeyboardVisibility(boolean visible);
-
-    // when the keyguard is up, it manages the power state, and userActivity doesn't do anything.
-    void enableUserActivity(boolean enabled);
-
-    // the same as the method on PowerManager
-    void userActivity(long time, boolean noChangeLights, int eventType);
-
-    boolean isScreenOn();
-
-    void setScreenBrightnessOverride(int brightness);
-    void setButtonBrightnessOverride(int brightness);
 }
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index a757303..efdbcac 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.content.Context;
 import android.util.Log;
 
 /**
@@ -42,8 +43,8 @@
  * wl.release();
  * }
  * </p><p>
- * The following flags are defined, with varying effects on system power.
- * <i>These flags are mutually exclusive - you may only specify one of them.</i>
+ * The following wake lock levels are defined, with varying effects on system power.
+ * <i>These levels are mutually exclusive - you may only specify one of them.</i>
  *
  * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
  *     <thead>
@@ -177,7 +178,7 @@
     /**
      * Wake lock level: Turns the screen off when the proximity sensor activates.
      * <p>
-     * Since not all devices have proximity sensors, use {@link #getSupportedWakeLockFlags}
+     * Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
      * to determine whether this wake lock level is supported.
      * </p>
      *
@@ -227,29 +228,24 @@
     public static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
 
     /**
-     * Brightness value to use when battery is low.
-     * @hide
-     */
-    public static final int BRIGHTNESS_LOW_BATTERY = 10;
-
-    /**
      * Brightness value for fully on.
      * @hide
      */
     public static final int BRIGHTNESS_ON = 255;
 
     /**
-     * Brightness value for dim backlight.
-     * @hide
-     */
-    public static final int BRIGHTNESS_DIM = 20;
-
-    /**
      * Brightness value for fully off.
      * @hide
      */
     public static final int BRIGHTNESS_OFF = 0;
 
+    /**
+     * A nominal default brightness value.
+     * Use {@link #getDefaultScreenBrightnessSetting()} instead.
+     * @hide
+     */
+    private static final int BRIGHTNESS_DEFAULT = 102;
+
     // Note: Be sure to update android.os.BatteryStats and PowerManager.h
     // if adding or modifying user activity event constants.
 
@@ -271,18 +267,82 @@
      */
     public static final int USER_ACTIVITY_EVENT_TOUCH = 2;
 
+    /**
+     * User activity flag: Do not restart the user activity timeout or brighten
+     * the display in response to user activity if it is already dimmed.
+     * @hide
+     */
+    public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0;
+
+    /**
+     * Special wake lock tag used for the wake lock in the Window Manager that handles the
+     * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} flag.
+     * @hide
+     */
+    public static final String KEEP_SCREEN_ON_FLAG_TAG = "KEEP_SCREEN_ON_FLAG";
+
+    /**
+     * Go to sleep reason code: Going to sleep due by user request.
+     * @hide
+     */
+    public static final int GO_TO_SLEEP_REASON_USER = 0;
+
+    /**
+     * Go to sleep reason code: Going to sleep due by request of the
+     * device administration policy.
+     * @hide
+     */
+    public static final int GO_TO_SLEEP_REASON_DEVICE_ADMIN = 1;
+
+    /**
+     * Go to sleep reason code: Going to sleep due to a screen timeout.
+     * @hide
+     */
+    public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;
+
+    final Context mContext;
     final IPowerManager mService;
     final Handler mHandler;
 
     /**
      * {@hide}
      */
-    public PowerManager(IPowerManager service, Handler handler) {
+    public PowerManager(Context context, IPowerManager service, Handler handler) {
+        mContext = context;
         mService = service;
         mHandler = handler;
     }
 
     /**
+     * Gets the minimum supported screen brightness setting.
+     * The screen may be allowed to become dimmer than this value but
+     * this is the minimum value that can be set by the user.
+     * @hide
+     */
+    public int getMinimumScreenBrightnessSetting() {
+        return mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_screenBrightnessDim);
+    }
+
+    /**
+     * Gets the maximum supported screen brightness setting.
+     * The screen may be allowed to become dimmer than this value but
+     * this is the maximum value that can be set by the user.
+     * @hide
+     */
+    public int getMaximumScreenBrightnessSetting() {
+        return BRIGHTNESS_ON;
+    }
+
+    /**
+     * Gets the default screen brightness setting.
+     * @hide
+     */
+    public int getDefaultScreenBrightnessSetting() {
+        return BRIGHTNESS_DEFAULT;
+    }
+
+    /**
      * Creates a new wake lock with the specified level and flags.
      * <p>
      * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags
@@ -360,8 +420,10 @@
     /**
      * Notifies the power manager that user activity happened.
      * <p>
-     * Turns the device from whatever state it's in to full on, and resets
-     * the auto-off timer.
+     * Resets the auto-off timer and brightens the screen if the device
+     * is not asleep.  This is what happens normally when a key or the touch
+     * screen is pressed or when some other user activity occurs.
+     * This method does not wake up the device if it has been put to sleep.
      * </p><p>
      * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
      * </p>
@@ -375,10 +437,14 @@
      * We want the device to stay on while the button is down, but we're about
      * to turn off the screen so we don't want the keyboard backlight to turn on again.
      * Otherwise the lights flash on and then off and it looks weird.
+     *
+     * @see #wakeUp
+     * @see #goToSleep
      */
     public void userActivity(long when, boolean noChangeLights) {
         try {
-            mService.userActivity(when, noChangeLights);
+            mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER,
+                    noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0);
         } catch (RemoteException e) {
         }
     }
@@ -386,8 +452,8 @@
    /**
      * Forces the device to go to sleep.
      * <p>
-     * Overrides all the wake locks that are held.  This is what happen when the power
-     * key is pressed to turn off the screen.
+     * Overrides all the wake locks that are held.
+     * This is what happens when the power key is pressed to turn off the screen.
      * </p><p>
      * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
      * </p>
@@ -396,10 +462,37 @@
      * {@link SystemClock#uptimeMillis()} time base.  This timestamp is used to correctly
      * order the user activity with other power management functions.  It should be set
      * to the timestamp of the input event that caused the request to go to sleep.
+     *
+     * @see #userActivity
+     * @see #wakeUp
      */
     public void goToSleep(long time) {
         try {
-            mService.goToSleep(time);
+            mService.goToSleep(time, GO_TO_SLEEP_REASON_USER);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Forces the device to wake up from sleep.
+     * <p>
+     * If the device is currently asleep, wakes it up, otherwise does nothing.
+     * This is what happens when the power key is pressed to turn on the screen.
+     * </p><p>
+     * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+     * </p>
+     *
+     * @param time The time when the request to wake up was issued, in the
+     * {@link SystemClock#uptimeMillis()} time base.  This timestamp is used to correctly
+     * order the user activity with other power management functions.  It should be set
+     * to the timestamp of the input event that caused the request to wake up.
+     *
+     * @see #userActivity
+     * @see #goToSleep
+     */
+    public void wakeUp(long time) {
+        try {
+            mService.wakeUp(time);
         } catch (RemoteException e) {
         }
     }
@@ -416,34 +509,24 @@
      */
     public void setBacklightBrightness(int brightness) {
         try {
-            mService.setBacklightBrightness(brightness);
+            mService.setTemporaryScreenBrightnessSettingOverride(brightness);
         } catch (RemoteException e) {
         }
     }
 
    /**
-     * Returns the set of wake lock levels and flags for {@link #newWakeLock}
-     * that are supported on the device.
-     * <p>
-     * For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK}
-     * is supported:
-     * {@samplecode
-     * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-     * int supportedFlags = pm.getSupportedWakeLockFlags();
-     * boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
-     *         == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK);
-     * }
-     * </p>
+     * Returns true if the specified wake lock level is supported.
      *
-     * @return The set of supported WakeLock flags.
+     * @param level The wake lock level to check.
+     * @return True if the specified wake lock level is supported.
      *
      * {@hide}
      */
-    public int getSupportedWakeLockFlags() {
+    public boolean isWakeLockLevelSupported(int level) {
         try {
-            return mService.getSupportedWakeLockFlags();
+            return mService.isWakeLockLevelSupported(level);
         } catch (RemoteException e) {
-            return 0;
+            return false;
         }
     }
 
@@ -593,7 +676,7 @@
                 // been explicitly released by the keyguard.
                 mHandler.removeCallbacks(mReleaser);
                 try {
-                    mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource);
+                    mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
                 } catch (RemoteException e) {
                 }
                 mHeld = true;
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index a85f4fa..ba77df7 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -1,5 +1,9 @@
 package android.os;
 
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Arrays;
+
 /**
  * Describes the source of some work that may be done by someone else.
  * Currently the public representation of what a work source is is not
@@ -313,6 +317,20 @@
         dest.writeIntArray(mUids);
     }
 
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("{WorkSource: uids=[");
+        for (int i = 0; i < mNum; i++) {
+            if (i != 0) {
+                result.append(", ");
+            }
+            result.append(mUids[i]);
+        }
+        result.append("]}");
+        return result.toString();
+    }
+
     public static final Parcelable.Creator<WorkSource> CREATOR
             = new Parcelable.Creator<WorkSource>() {
         public WorkSource createFromParcel(Parcel in) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 01252f0..e08ec1f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1381,7 +1381,9 @@
 
         /**
          * Whether or not to dim the screen. 0=no  1=yes
+         * @deprecated This setting is no longer used.
          */
+        @Deprecated
         public static final String DIM_SCREEN = "dim_screen";
 
         /**
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
index dd177cb..fc3f501 100644
--- a/core/java/android/service/dreams/DreamManagerService.java
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -123,7 +123,9 @@
     // IDreamManager method
     @Override
     public boolean isDreaming() {
-        return mCurrentDream != null;
+        synchronized (mLock) {
+            return mCurrentDreamToken != null;
+        }
     }
 
     public void bindDreamComponentL(ComponentName componentName, boolean test) {
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 7d33ff4a..5a4f322 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.os.SystemClock;
 import android.text.format.DateUtils;
 
 import com.android.internal.util.XmlUtils;
@@ -391,6 +392,18 @@
         formatDuration(time-now, pw, 0);
     }
 
+    /** @hide Just for debugging; not internationalized. */
+    public static String formatUptime(long time) {
+        final long diff = time - SystemClock.uptimeMillis();
+        if (diff > 0) {
+            return time + " (in " + diff + " ms)";
+        }
+        if (diff < 0) {
+            return time + " (" + -diff + " ms ago)";
+        }
+        return time + " (now)";
+    }
+
     /**
      * Convert a System.currentTimeMillis() value to a time of day value like
      * that printed in logs. MM-DD HH:MM:SS.MMM
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 407bae5..7aa3bb4 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -22,7 +22,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.IBinder;
-import android.os.LocalPowerManager;
 import android.os.Looper;
 import android.view.animation.Animation;
 
@@ -115,11 +114,11 @@
     public final static int ACTION_PASS_TO_USER = 0x00000001;
 
     /**
-     * This key event should extend the user activity timeout and turn the lights on.
+     * This key event should wake the device.
      * To be returned from {@link #interceptKeyBeforeQueueing}.
      * Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
      */
-    public final static int ACTION_POKE_USER_ACTIVITY = 0x00000002;
+    public final static int ACTION_WAKE_UP = 0x00000002;
 
     /**
      * This key event should put the device to sleep (and engage keyguard if necessary)
@@ -473,11 +472,9 @@
      * Perform initialization of the policy.
      * 
      * @param context The system context we are running in.
-     * @param powerManager 
      */
     public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs,
-            LocalPowerManager powerManager);
+            WindowManagerFuncs windowManagerFuncs);
 
     /**
      * Called by window manager once it has the initial, default native
@@ -1093,31 +1090,6 @@
     public void lockNow();
 
     /**
-     * Check to see if a screensaver should be run instead of powering off the screen on timeout. 
-     * 
-     * @return true if the screensaver should run, false if the screen should turn off.
-     * 
-     * @hide
-     */
-    public boolean isScreenSaverEnabled();
-
-    /**
-     * Start the screensaver (if it is enabled and not yet running).
-     * 
-     * @return Whether the screensaver was successfully started.
-     * 
-     * @hide
-     */
-    public boolean startScreenSaver();
-
-    /**
-     * Stop the screensaver if it is running.
-     * 
-     * @hide
-     */
-    public void stopScreenSaver();
-
-    /**
      * Set the last used input method window state. This state is used to make IME transition
      * smooth.
      * @hide
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 30c713e..2b75d83 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -37,8 +37,8 @@
     /**
      * Gets the singleton CookieManager instance. If this method is used
      * before the application instantiates a {@link WebView} instance,
-     * {@link CookieSyncManager#createInstance(Context)} must be called
-     * first.
+     * {@link CookieSyncManager#createInstance CookieSyncManager.createInstance(Context)}
+     * must be called first.
      *
      * @return the singleton CookieManager instance
      */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 63a79e4..a5420bb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -164,10 +164,7 @@
  *
  * <p>For obvious security reasons, your application has its own
  * cache, cookie store etc.&mdash;it does not share the Browser
- * application's data. Cookies are managed on a separate thread, so
- * operations like index building don't block the UI
- * thread. Follow the instructions in {@link android.webkit.CookieSyncManager}
- * if you want to use cookies in your application.
+ * application's data.
  * </p>
  *
  * <p>By default, requests by the HTML to open new windows are
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 5b8764b..1acbab1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -378,28 +378,26 @@
                     imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS;
                 }
             }
+            int action = EditorInfo.IME_ACTION_GO;
             switch (type) {
                 case WebTextView.NORMAL_TEXT_FIELD:
-                    imeOptions |= EditorInfo.IME_ACTION_GO;
                     break;
                 case WebTextView.TEXT_AREA:
                     inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE
                             | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
                             | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
-                    imeOptions |= EditorInfo.IME_ACTION_NONE;
+                    action = EditorInfo.IME_ACTION_NONE;
                     break;
                 case WebTextView.PASSWORD:
                     inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
-                    imeOptions |= EditorInfo.IME_ACTION_GO;
                     break;
                 case WebTextView.SEARCH:
-                    imeOptions |= EditorInfo.IME_ACTION_SEARCH;
+                    action = EditorInfo.IME_ACTION_SEARCH;
                     break;
                 case WebTextView.EMAIL:
                     // inputType needs to be overwritten because of the different text variation.
                     inputType = InputType.TYPE_CLASS_TEXT
                             | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
-                    imeOptions |= EditorInfo.IME_ACTION_GO;
                     break;
                 case WebTextView.NUMBER:
                     // inputType needs to be overwritten because of the different class.
@@ -407,23 +405,20 @@
                             | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL;
                     // Number and telephone do not have both a Tab key and an
                     // action, so set the action to NEXT
-                    imeOptions |= EditorInfo.IME_ACTION_NEXT;
                     break;
                 case WebTextView.TELEPHONE:
                     // inputType needs to be overwritten because of the different class.
                     inputType = InputType.TYPE_CLASS_PHONE;
-                    imeOptions |= EditorInfo.IME_ACTION_NEXT;
                     break;
                 case WebTextView.URL:
                     // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
                     // exclude it for now.
-                    imeOptions |= EditorInfo.IME_ACTION_GO;
                     inputType |= InputType.TYPE_TEXT_VARIATION_URI;
                     break;
                 default:
-                    imeOptions |= EditorInfo.IME_ACTION_GO;
                     break;
             }
+            imeOptions |= action;
             mHint = initData.mLabel;
             mInputType = inputType;
             mImeOptions = imeOptions;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 6630601..216344d 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -500,19 +500,15 @@
         log("Turn screen off");
         PowerManager pm =
             (PowerManager) getSystemService(Context.POWER_SERVICE);
-        pm.goToSleep(SystemClock.uptimeMillis() + 100);
+        pm.goToSleep(SystemClock.uptimeMillis());
     }
 
     // Turn screen on
     public void turnScreenOn() {
         log("Turn screen on");
-        IPowerManager mPowerManagerService = IPowerManager.Stub.asInterface(
-                ServiceManager.getService("power"));;
-        try {
-            mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
-        } catch (Exception e) {
-            log(e.toString());
-        }
+        PowerManager pm =
+                (PowerManager) getSystemService(Context.POWER_SERVICE);
+        pm.wakeUp(SystemClock.uptimeMillis());
     }
 
     /**
diff --git a/core/tests/coretests/src/android/os/BrightnessLimit.java b/core/tests/coretests/src/android/os/BrightnessLimit.java
index 5e9b906..f4a5e09 100644
--- a/core/tests/coretests/src/android/os/BrightnessLimit.java
+++ b/core/tests/coretests/src/android/os/BrightnessLimit.java
@@ -49,7 +49,7 @@
                 ServiceManager.getService("power"));
         if (power != null) {
             try {
-                power.setBacklightBrightness(0);
+                power.setTemporaryScreenBrightnessSettingOverride(0);
             } catch (RemoteException darn) {
                 
             }
diff --git a/docs/html/guide/topics/search/index.jd b/docs/html/guide/topics/search/index.jd
index 2ee624b..680c607 100644
--- a/docs/html/guide/topics/search/index.jd
+++ b/docs/html/guide/topics/search/index.jd
@@ -54,9 +54,9 @@
 if your data is stored in an SQLite database, you should use the {@link android.database.sqlite}
 APIs to perform searches.
 <br/><br/>
-Also, there is no guarantee that every device provides a dedicated SEARCH button to invoke the
+Also, there is no guarantee that a device provides a dedicated SEARCH button that invokes the
 search interface in your application. When using the search dialog or a custom interface, you
-must always provide a search button in your UI that activates the search interface. For more
+must provide a search button in your UI that activates the search interface. For more
 information, see <a href="search-dialog.html#InvokingTheSearchDialog">Invoking the search
 dialog</a>.</p>
 
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index 49451ac..b9a26d6 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -6,14 +6,6 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-  <h2>Quickview</h2>
-  <ul>
-    <li>The Android system sends search queries from the search dialog or widget to an activity you
-specify to perform searches and present results</li>
-    <li>You can put the search widget in the Action Bar, as an "action view," for quick
-access</li>
-  </ul>
-
 
 <h2>In this document</h2>
 <ol>
@@ -61,14 +53,8 @@
 
 <h2>Downloads</h2>
 <ol>
-<li><a href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a></li>
-</ol>
-
-<h2>See also</h2>
-<ol>
-<li><a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a></li>
-<li><a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></li>
-<li><a href="searchable-config.html">Searchable Configuration</a></li>
+<li><a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar
+Icon Pack</a></li>
 </ol>
 
 </div>
@@ -142,12 +128,14 @@
   <li>A search interface, provided by either:
     <ul>
       <li>The search dialog
-        <p>By default, the search dialog is hidden, but appears at the top of the screen when the 
-user presses the device SEARCH button (when available) or another button in your user interface.</p>
+        <p>By default, the search dialog is hidden, but appears at the top of the screen when
+          you call {@link android.app.Activity#onSearchRequested()} (when the user presses your
+          Search button).</p>
       </li>
       <li>Or, a {@link android.widget.SearchView} widget
         <p>Using the search widget allows you to put the search box anywhere in your activity.
-Instead of putting it in your activity layout, however, it's usually more convenient for users as an
+Instead of putting it in your activity layout, you should usually use
+{@link android.widget.SearchView} as an 
 <a href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>.</p>
       </li>
     </ul>
@@ -415,10 +403,9 @@
 your application for devices running Android 3.0, you should consider using the search widget
 instead (see the side box).</p>
 
-<p>The search dialog is always hidden by default, until the user activates it. If the user's device
-includes a SEARCH button, pressing it will activate the search dialog by default. Your application
-can also activate the search dialog on demand by calling {@link
-android.app.Activity#onSearchRequested onSearchRequested()}. However, neither of these work
+<p>The search dialog is always hidden by default, until the user activates it. Your application
+can activate the search dialog by calling {@link
+android.app.Activity#onSearchRequested onSearchRequested()}. However, this method doesn't work
 until you enable the search dialog for the activity.</p>
 
 <p>To enable the search dialog, you must indicate to the system which searchable activity should
@@ -469,8 +456,8 @@
 href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
 element to declare which searchable activity to use for searches, the activity has enabled the
 search dialog.
-While the user is in this activity, the device SEARCH button (if available) and the {@link
-android.app.Activity#onSearchRequested onSearchRequested()} method will activate the search dialog.
+While the user is in this activity, the {@link
+android.app.Activity#onSearchRequested onSearchRequested()} method activates the search dialog.
 When the user executes the search, the system starts {@code SearchableActivity} and delivers it
 the {@link android.content.Intent#ACTION_SEARCH} intent.</p>
 
@@ -495,21 +482,22 @@
 
 <h3 id="InvokingTheSearchDialog">Invoking the search dialog</h3>
 
-<p>As mentioned above, the device SEARCH button will open the search dialog as long as the current
-activity has declared in the manifest the searchable activity to use.</p>
+<p>Although some devices provide a dedicated Search button, the behavior of the button may vary
+between devices and many devices do not provide a Search button at all. So when using the search
+dialog, you <strong>must provide a search button in your UI</strong> that activates the search
+dialog by calling {@link android.app.Activity#onSearchRequested()}.</p>
 
-<p>However, some devices do not include a dedicated SEARCH button, so you should not assume that
-it's always available. When using the search dialog, you must <strong>always provide another search
-button in your UI</strong> that activates the search dialog by calling {@link
-android.app.Activity#onSearchRequested()}.</p>
+<p>For instance, you should add a Search button in your <a
+href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or UI
+layout that calls {@link android.app.Activity#onSearchRequested()}. For consistency with
+the Android system and other apps, you should label your button with the Android Search icon that's
+available from the <a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar
+Icon Pack</a>.</p>
 
-<p>For instance, you should either provide a menu item in your <a
-href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or a button in your
-activity layout that
-activates search by calling {@link android.app.Activity#onSearchRequested()}. The <a
-href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a> file includes icons for
-medium and high density screens, which you can use for your search menu item or button (low-density
-screens scale-down the hdpi image by one half). </p>
+<p class="note"><strong>Note:</strong> If your app uses the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>, then you should not use
+the search dialog for your search interface. Instead, use the <a href="#UsingSearchWidget">search
+widget</a> as a collapsible view in the action bar.</p>
 
 <p>You can also enable "type-to-search" functionality, which activates the search dialog when the
 user starts typing on the keyboard&mdash;the keystrokes are inserted into the search dialog. You can
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index a596fa9..b352ffc 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -699,7 +699,6 @@
     }
 
 #if DEBUG_FONT_RENDERER
-    ALOGD("FontRenderer: flushAllAndInvalidatel");
     // Erase caches, just as a debugging facility
     if (mCacheTextureSmall && mCacheTextureSmall->mTexture) {
         memset(mCacheTextureSmall->mTexture, 0,
@@ -792,14 +791,12 @@
 
 void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
         uint32_t* retOriginX, uint32_t* retOriginY) {
+    checkInit();
     cachedGlyph->mIsValid = false;
     // If the glyph is too tall, don't cache it
-    if (mCacheLines.size() == 0 ||
-        glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
-        if (mCacheLines.size() != 0) {
-            ALOGE("Font size too large to fit in cache. width, height = %i, %i",
-                    (int) glyph.fWidth, (int) glyph.fHeight);
-        }
+    if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
+        ALOGE("Font size too large to fit in cache. width, height = %i, %i",
+                (int) glyph.fWidth, (int) glyph.fHeight);
         return;
     }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 18e7faa..9208cae 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -109,7 +109,7 @@
             IPowerManager power = IPowerManager.Stub.asInterface(
                     ServiceManager.getService("power"));
             if (power != null) {
-                power.setBacklightBrightness(brightness);
+                power.setTemporaryScreenBrightnessSettingOverride(brightness);
             }
         } catch (RemoteException doe) {
 
diff --git a/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png b/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png
new file mode 100644
index 0000000..47c89b1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
index 47c511c..b68632a 100644
--- a/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
@@ -36,11 +36,17 @@
         android:id="@+id/panel_holder"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layout_marginTop="@*android:dimen/status_bar_height"
         >
         <include layout="@layout/status_bar_expanded"
             android:layout_width="@dimen/notification_panel_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal|top"
+            android:layout_gravity="left|top"
+            />
+        <include layout="@layout/quick_settings"
+            android:layout_width="@dimen/notification_panel_width"
+            android:layout_height="wrap_content"
+            android:layout_gravity="right|top"
             />
     </com.android.systemui.statusbar.phone.PanelHolder>
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/layout/quick_settings.xml b/packages/SystemUI/res/layout/quick_settings.xml
new file mode 100644
index 0000000..a62a470
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<com.android.systemui.statusbar.phone.PanelView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:id="@+id/settings_panel"
+    >
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:scaleType="centerInside"
+        android:src="@drawable/qs_coming_soon"
+        android:padding="4dp"
+        android:background="#80000080"
+        />
+    <LinearLayout android:id="@+id/handle"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/close_handle_height"
+        android:layout_gravity="bottom"
+        android:orientation="vertical"
+        >
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/close_handle_height"
+            android:layout_gravity="bottom"
+            android:scaleType="fitXY"
+            android:src="@drawable/status_bar_close"
+            />
+    </LinearLayout>
+</com.android.systemui.statusbar.phone.PanelView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index ad905bd..ad6b8f4 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -36,11 +36,16 @@
         android:id="@+id/panel_holder"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
+        android:layout_marginTop="@*android:dimen/status_bar_height"
         >
         <include layout="@layout/status_bar_expanded"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             />
+        <include layout="@layout/quick_settings"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
     </com.android.systemui.statusbar.phone.PanelHolder>
 
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index afa0b20..c6c0719 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -19,8 +19,4 @@
     <!-- Layout parameters for the notification panel -->
 	<dimen name="notification_panel_margin_bottom">0dp</dimen>
     <dimen name="notification_panel_margin_left">32dp</dimen>
-
-    <!-- Gravity for the notification panel -->
-    <!-- 0x33 = left|top -->
-    <integer name="notification_panel_layout_gravity">0x33</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 2b5248f..b6faff3 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -21,11 +21,12 @@
 
     <!-- Layout parameters for the notification panel -->
     <dimen name="notification_panel_margin_bottom">192dp</dimen>
-    <dimen name="notification_panel_margin_left">0dp</dimen>
+    <dimen name="notification_panel_margin_left">16dp</dimen>
 
-    <!-- Gravity for the notification panel -->
-    <!-- 0x33 = center_horizontal|top -->
-    <integer name="notification_panel_layout_gravity">0x31</integer>
+    <!-- Gravity for the notification & quick settings panels -->
+    <!-- 0x33 = left|top ; 0x35 = right|top -->
+    <integer name="notification_panel_layout_gravity">0x33</integer>
+    <integer name="settings_panel_layout_gravity">0x35</integer>
 
     <!-- Diameter of outer shape drawable shown in navbar search-->
     <dimen name="navbar_search_outerring_diameter">430dip</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8204e95..9539373 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -158,9 +158,10 @@
     <dimen name="notification_panel_margin_bottom">0dp</dimen>
     <dimen name="notification_panel_margin_left">0dp</dimen>
 
-    <!-- Gravity for the notification panel -->
+    <!-- Gravity for the notification & quick settings panels -->
     <!-- 0x37 = fill_horizontal|top -->
     <integer name="notification_panel_layout_gravity">0x37</integer>
+    <integer name="settings_panel_layout_gravity">0x37</integer>
 
     <!-- Height of the carrier/wifi name label -->
     <dimen name="carrier_label_height">24dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index b2c72e8..f44c500 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -9,7 +9,7 @@
 import android.widget.FrameLayout;
 
 public class PanelBar extends FrameLayout {
-    public static final boolean DEBUG = true;
+    public static final boolean DEBUG = false;
     public static final String TAG = PanelView.class.getSimpleName();
     public static final void LOG(String fmt, Object... args) {
         if (!DEBUG) return;
@@ -18,7 +18,17 @@
 
     private PanelHolder mPanelHolder;
     private ArrayList<PanelView> mPanels = new ArrayList<PanelView>();
-    private PanelView mTouchingPanel;
+    protected PanelView mTouchingPanel;
+    private static final int STATE_CLOSED = 0;
+    private static final int STATE_TRANSITIONING = 1;
+    private static final int STATE_OPEN = 2;
+    private int mState = STATE_CLOSED;
+    private boolean mTracking;
+
+    private void go(int state) {
+        LOG("go state: %d -> %d", mState, state);
+        mState = state;
+    }
 
     public PanelBar(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -62,8 +72,11 @@
             final int i = (int)(N * event.getX() / getMeasuredWidth());
             mTouchingPanel = mPanels.get(i);
             mPanelHolder.setSelectedPanel(mTouchingPanel);
-            LOG("PanelBar.onTouch: ACTION_DOWN: panel %d", i);
-            onPanelPeeked();
+            LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %d", mState, i);
+            if (mState == STATE_CLOSED || mState == STATE_OPEN) {
+                go(STATE_TRANSITIONING);
+                onPanelPeeked();
+            }
         }
         final boolean result = mTouchingPanel.getHandle().dispatchTouchEvent(event);
         return result;
@@ -71,24 +84,31 @@
 
     public void panelExpansionChanged(PanelView panel, float frac) {
         boolean fullyClosed = true;
-        boolean fullyOpened = false;
+        PanelView fullyOpenedPanel = null;
+        LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
         for (PanelView pv : mPanels) {
+            // adjust any other panels that may be partially visible
             if (pv.getExpandedHeight() > 0f) {
                 fullyClosed = false;
                 final float thisFrac = pv.getExpandedFraction();
-                LOG("panel %s: f=%.1f", pv, thisFrac);
+                LOG("panelExpansionChanged:  -> %s: f=%.1f", pv.getName(), thisFrac);
                 if (panel == pv) {
-                    if (thisFrac == 1f) fullyOpened = true;
+                    if (thisFrac == 1f) fullyOpenedPanel = panel;
                 } else {
                     pv.setExpandedFraction(1f-frac);
                 }
             }
         }
-        if (fullyOpened) onPanelFullyOpened();
-        if (fullyClosed) onAllPanelsCollapsed();
-        else onPanelPeeked();
+        if (fullyOpenedPanel != null && !mTracking) {
+            go(STATE_OPEN);
+            onPanelFullyOpened(fullyOpenedPanel);
+        } else if (fullyClosed && !mTracking) {
+            go(STATE_CLOSED);
+            onAllPanelsCollapsed();
+        }
 
-        LOG("panelExpansionChanged: [%s%s ]", fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":"");
+        LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
+                (fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
     }
 
     public void collapseAllPanels(boolean animate) {
@@ -109,7 +129,20 @@
         LOG("onAllPanelsCollapsed");
     }
 
-    public void onPanelFullyOpened() {
+    public void onPanelFullyOpened(PanelView openPanel) {
         LOG("onPanelFullyOpened");
     }
+
+    public void onTrackingStarted(PanelView panel) {
+        mTracking = true;
+        if (panel != mTouchingPanel) {
+            LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
+                    panel, mTouchingPanel);
+        }
+    }
+
+    public void onTrackingStopped(PanelView panel) {
+        mTracking = false;
+        panelExpansionChanged(panel, panel.getExpandedFraction());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 7dc8f7c..b5a50c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -14,11 +14,11 @@
 import com.android.systemui.R;
 
 public class PanelView extends FrameLayout {
-    public static final boolean DEBUG = true;
+    public static final boolean DEBUG = false;
     public static final String TAG = PanelView.class.getSimpleName();
-    public static final void LOG(String fmt, Object... args) {
+    public final void LOG(String fmt, Object... args) {
         if (!DEBUG) return;
-        Log.v(TAG, String.format(fmt, args));
+        Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
     }
 
     public static final boolean BRAKES = false;
@@ -61,6 +61,7 @@
 
     private float mVel, mAccel;
     private int mFullHeight = 0;
+    private String mViewName; 
 
     private void animationTick(long dtms) {
         if (!mTimeAnimator.isStarted()) {
@@ -69,7 +70,7 @@
             mTimeAnimator.setTimeListener(mAnimationCallback);
 
             mTimeAnimator.start();
-        } else {
+        } else if (dtms > 0) {
             final float dt = dtms * 0.001f;                  // ms -> s
             LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
             LOG("tick: before: h=%d", (int) mExpandedHeight);
@@ -170,13 +171,16 @@
                 public boolean onTouch(View v, MotionEvent event) {
                     final float y = event.getY();
                     final float rawY = event.getRawY();
-                    LOG("handle.onTouch: y=%.1f rawY=%.1f off=%.1f", y, rawY, mTouchOffset);
+                    LOG("handle.onTouch: a=%s y=%.1f rawY=%.1f off=%.1f",
+                            MotionEvent.actionToString(event.getAction()),
+                            y, rawY, mTouchOffset);
                     PanelView.this.getLocationOnScreen(mAbsPos);
 
                     switch (event.getAction()) {
                         case MotionEvent.ACTION_DOWN:
                             mVelocityTracker = VelocityTracker.obtain();
                             trackMovement(event);
+                            mBar.onTrackingStarted(PanelView.this);
                             mTouchOffset = (rawY - mAbsPos[1]) - PanelView.this.getExpandedHeight();
                             break;
 
@@ -190,6 +194,7 @@
 
                         case MotionEvent.ACTION_UP:
                         case MotionEvent.ACTION_CANCEL:
+                            mBar.onTrackingStopped(PanelView.this);
                             trackMovement(event);
                             mVelocityTracker.computeCurrentVelocity(1000);
 
@@ -241,6 +246,11 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
+        mViewName = getResources().getResourceName(getId());
+    }
+
+    public String getName() {
+        return mViewName;
     }
 
     @Override
@@ -278,7 +288,7 @@
         }
 
         LOG("setExpansion: height=%.1f fh=%.1f", h, fh);
-        
+
         if (h < 0) h = 0;
         else if (h > fh) h = fh;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 0f84c2f..4d4adcb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -169,12 +169,16 @@
     PanelView mNotificationPanel; // the sliding/resizing panel within the notification window
     ScrollView mScrollView;
     View mExpandedContents;
-    int mNotificationPanelMarginBottomPx, mNotificationPanelMarginLeftPx;
     final Rect mNotificationPanelBackgroundPadding = new Rect();
     int mNotificationPanelGravity;
+    int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
     int mNotificationPanelMinHeight;
     boolean mNotificationPanelIsFullScreenWidth;
 
+    // settings
+    PanelView mSettingsPanel;
+    int mSettingsPanelGravity;
+
     // top bar
     View mClearButton;
     View mSettingsButton;
@@ -310,22 +314,29 @@
 
         mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
         // don't allow clicks on the panel to pass through to the background where they will cause the panel to close
-        mNotificationPanel.setOnTouchListener(new View.OnTouchListener() {
+        View.OnTouchListener clickStopper = new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
                 return true;
             }
-        });
+        };
+        mNotificationPanel.setOnTouchListener(clickStopper);
         mNotificationPanelIsFullScreenWidth =
             (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
         mNotificationPanel.setSystemUiVisibility(
                   View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
                 | (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO));
 
+        // quick settings (WIP)
+        mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
+        mSettingsPanel.setOnTouchListener(clickStopper);
+
         if (!ActivityManager.isHighEndGfx(mDisplay)) {
             mStatusBarWindow.setBackground(null);
             mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
                     R.color.notification_panel_solid_background)));
+            mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
+                    R.color.notification_panel_solid_background)));
         }
         if (ENABLE_INTRUDERS) {
             mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
@@ -1634,8 +1645,12 @@
         if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
         lp.gravity = mNotificationPanelGravity;
-        lp.leftMargin = mNotificationPanelMarginLeftPx;
+        lp.leftMargin = mNotificationPanelMarginPx;
         mNotificationPanel.setLayoutParams(lp);
+        lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
+        lp.gravity = mSettingsPanelGravity;
+        lp.rightMargin = mNotificationPanelMarginPx;
+        mSettingsPanel.setLayoutParams(lp);
     }
 
     // called by makeStatusbar and also by PhoneStatusBarView
@@ -1872,11 +1887,15 @@
 
         mNotificationPanelMarginBottomPx
             = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
-        mNotificationPanelMarginLeftPx
+        mNotificationPanelMarginPx
             = (int) res.getDimension(R.dimen.notification_panel_margin_left);
         mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
         if (mNotificationPanelGravity <= 0) {
-            mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
+            mNotificationPanelGravity = Gravity.LEFT | Gravity.TOP;
+        }
+        mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
+        if (mSettingsPanelGravity <= 0) {
+            mSettingsPanelGravity = Gravity.RIGHT | Gravity.TOP;
         }
         getNinePatchPadding(res.getDrawable(R.drawable.notification_panel_bg), mNotificationPanelBackgroundPadding);
         final int notificationPanelDecorationHeight =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 6de0153..25ff9aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -42,6 +42,7 @@
     private static final String TAG = "PhoneStatusBarView";
     PhoneStatusBar mBar;
     int mScrimColor;
+    PanelView mFadingPanel = null;
 
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -76,12 +77,21 @@
     public void onPanelPeeked() {
         super.onPanelPeeked();
         mBar.makeExpandedVisible(true);
+        if (mFadingPanel == null) {
+            mFadingPanel = mTouchingPanel;
+        }
     }
 
     @Override
     public void onAllPanelsCollapsed() {
         super.onAllPanelsCollapsed();
         mBar.makeExpandedInvisible();
+        mFadingPanel = null;
+    }
+
+    @Override
+    public void onPanelFullyOpened(PanelView openPanel) {
+        mFadingPanel = openPanel;
     }
 
     @Override
@@ -98,7 +108,8 @@
     public void panelExpansionChanged(PanelView pv, float frac) {
         super.panelExpansionChanged(pv, frac);
 
-        if (mScrimColor != 0 && ActivityManager.isHighEndGfx(mBar.mDisplay)) {
+        if (mFadingPanel == pv 
+                && mScrimColor != 0 && ActivityManager.isHighEndGfx(mBar.mDisplay)) {
             // woo, special effects
             final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2.2f))));
             // attenuate background color alpha by k
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
index 3ba36af..457e9dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.IPowerManager;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
@@ -31,8 +32,8 @@
 public class BrightnessController implements ToggleSlider.Listener {
     private static final String TAG = "StatusBar.BrightnessController";
 
-    private static final int MINIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_DIM;
-    private static final int MAXIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_ON;
+    private final int mMinimumBacklight;
+    private final int mMaximumBacklight;
 
     private Context mContext;
     private ToggleSlider mControl;
@@ -42,6 +43,10 @@
         mContext = context;
         mControl = control;
 
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
+        mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
+
         boolean automaticAvailable = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
         mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
@@ -65,11 +70,11 @@
             value = Settings.System.getInt(mContext.getContentResolver(), 
                     Settings.System.SCREEN_BRIGHTNESS);
         } catch (SettingNotFoundException ex) {
-            value = MAXIMUM_BACKLIGHT;
+            value = mMaximumBacklight;
         }
 
-        control.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);
-        control.setValue(value - MINIMUM_BACKLIGHT);
+        control.setMax(mMaximumBacklight - mMinimumBacklight);
+        control.setValue(value - mMinimumBacklight);
 
         control.setOnChangedListener(this);
     }
@@ -78,7 +83,7 @@
         setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
                 : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
         if (!automatic) {
-            final int val = value + MINIMUM_BACKLIGHT;
+            final int val = value + mMinimumBacklight;
             setBrightness(val);
             if (!tracking) {
                 AsyncTask.execute(new Runnable() {
@@ -98,7 +103,7 @@
     
     private void setBrightness(int brightness) {
         try {
-            mPower.setBacklightBrightness(brightness);
+            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
         } catch (RemoteException ex) {
         }        
     }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 1fb63db..66ccdac 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -33,7 +33,7 @@
 import android.media.AudioManager;
 import android.media.SoundPool;
 import android.os.Handler;
-import android.os.LocalPowerManager;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
@@ -156,10 +156,6 @@
     private boolean mSuppressNextLockSound = true;
 
 
-    /** Low level access to the power manager for enableUserActivity.  Having this
-     * requires that we run in the system process.  */
-    LocalPowerManager mRealPowerManager;
-
     /** High level access to the power manager for WakeLocks */
     private PowerManager mPM;
 
@@ -228,7 +224,7 @@
 
     private KeyguardUpdateMonitor mUpdateMonitor;
 
-    private boolean mScreenOn = false;
+    private boolean mScreenOn;
 
     // last known state of the cellular connection
     private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
@@ -357,11 +353,9 @@
 
     };
 
-    public KeyguardViewMediator(Context context, PhoneWindowManager callback,
-            LocalPowerManager powerManager) {
+    public KeyguardViewMediator(Context context, PhoneWindowManager callback) {
         mContext = context;
         mCallback = callback;
-        mRealPowerManager = powerManager;
         mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mWakeLock = mPM.newWakeLock(
                 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
@@ -393,6 +387,8 @@
         final ContentResolver cr = mContext.getContentResolver();
         mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
 
+        mScreenOn = mPM.isScreenOn();
+
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
         String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND);
         if (soundPath != null) {
@@ -974,7 +970,7 @@
      * interacts with the keyguard ui should be posted to this handler, rather
      * than called directly.
      */
-    private Handler mHandler = new Handler() {
+    private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -1031,7 +1027,7 @@
         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
         handleHide();
         if (wakeup) {
-            mPM.userActivity(SystemClock.uptimeMillis(), true);
+            mPM.wakeUp(SystemClock.uptimeMillis());
         }
         mWakeLock.release();
         mContext.sendBroadcast(mUserPresentIntent);
@@ -1164,7 +1160,8 @@
         // disable user activity if we are shown and not hidden
         if (DEBUG) Log.d(TAG, "adjustUserActivityLocked mShowing: " + mShowing + " mHidden: " + mHidden);
         boolean enabled = !mShowing || mHidden;
-        mRealPowerManager.enableUserActivity(enabled);
+        // FIXME: Replace this with a new timeout control mechanism.
+        //mRealPowerManager.enableUserActivity(enabled);
         if (!enabled && mScreenOn) {
             // reinstate our short screen timeout policy
             pokeWakelock();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 769b513..c036e1b 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -45,7 +45,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
-import android.os.LocalPowerManager;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
@@ -170,9 +169,6 @@
     static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
     static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
 
-    // Should screen savers use their own timeout, or the SCREEN_OFF_TIMEOUT?
-    static final boolean SEPARATE_TIMEOUT_FOR_SCREEN_SAVER = false;
-
     static final int LONG_PRESS_POWER_NOTHING = 0;
     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
     static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -280,7 +276,7 @@
     Context mContext;
     IWindowManager mWindowManager;
     WindowManagerFuncs mWindowManagerFuncs;
-    LocalPowerManager mPowerManager;
+    PowerManager mPowerManager;
     IStatusBarService mStatusBarService;
     final Object mServiceAquireLock = new Object();
     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
@@ -474,13 +470,6 @@
     int mLockScreenTimeout;
     boolean mLockScreenTimerActive;
 
-    // visual screen saver support
-    boolean mScreenSaverFeatureAvailable;
-    int mScreenSaverTimeout = 0;
-    boolean mScreenSaverEnabledByUser = false;
-    boolean mScreenSaverMayRun = true; // false if a wakelock is held
-    boolean mPluggedIn;
-
     // Behavior of ENDCALL Button.  (See Settings.System.END_BUTTON_BEHAVIOR.)
     int mEndcallBehavior;
 
@@ -572,12 +561,6 @@
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
             resolver.registerContentObserver(Settings.System.getUriFor(
                     "fancy_rotation_anim"), false, this);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.SCREENSAVER_ENABLED), false, this);
-            if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
-                resolver.registerContentObserver(Settings.Secure.getUriFor(
-                        "screensaver_timeout"), false, this);
-            } // otherwise SCREEN_OFF_TIMEOUT will do nicely
             updateSettings();
         }
 
@@ -863,16 +846,14 @@
 
     /** {@inheritDoc} */
     public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs,
-            LocalPowerManager powerManager) {
+            WindowManagerFuncs windowManagerFuncs) {
         mContext = context;
         mWindowManager = windowManager;
         mWindowManagerFuncs = windowManagerFuncs;
-        mPowerManager = powerManager;
         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
         if (!mHeadless) {
             // don't create KeyguardViewMediator if headless
-            mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
+            mKeyguardMediator = new KeyguardViewMediator(context, this);
         }
         mHandler = new PolicyHandler();
         mOrientationListener = new MyOrientationListener(mContext);
@@ -898,8 +879,8 @@
         mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
 
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                 "PhoneWindowManager.mBroadcastWakeLock");
         mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
         mLidOpenRotation = readRotation(
@@ -932,14 +913,6 @@
                     Intent.EXTRA_DOCK_STATE_UNDOCKED);
         }
 
-        // watch the plug to know whether to trigger the screen saver
-        filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        intent = context.registerReceiver(mPowerReceiver, filter);
-        if (intent != null) {
-            mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
-        }
-
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_longPressVibePattern);
@@ -1121,26 +1094,6 @@
                 mHasSoftInput = hasSoftInput;
                 updateRotation = true;
             }
-
-            // dreams
-            mScreenSaverFeatureAvailable = mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_enableDreams);
-            
-            mScreenSaverEnabledByUser = 0 != Settings.Secure.getInt(resolver,
-                    Settings.Secure.SCREENSAVER_ENABLED, 0);
-
-            if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
-                mScreenSaverTimeout = Settings.Secure.getInt(resolver,
-                        "screensaver_timeout", 0);
-            } else {
-                mScreenSaverTimeout = Settings.System.getInt(resolver,
-                        Settings.System.SCREEN_OFF_TIMEOUT, 0);
-                if (mScreenSaverTimeout > 0) {
-                    // We actually want to activate the screensaver just before the
-                    // power manager's screen timeout
-                    mScreenSaverTimeout -= 5000;
-                }
-            }
         }
         if (updateRotation) {
             updateRotation(true);
@@ -3018,12 +2971,10 @@
                 mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
                         KeyEvent.KEYCODE_POWER, mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
             } else {
-                mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
-                        PowerManager.USER_ACTIVITY_EVENT_BUTTON);
+                mPowerManager.wakeUp(SystemClock.uptimeMillis());
             }
         } else if (!mLidControlsSleep) {
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
-                    PowerManager.USER_ACTIVITY_EVENT_OTHER);
+            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
     }
 
@@ -3182,6 +3133,11 @@
     /** {@inheritDoc} */
     @Override
     public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
+        if (!mSystemBooted) {
+            // If we have not yet booted, don't let key events do anything.
+            return 0;
+        }
+
         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
         final boolean canceled = event.isCanceled();
         final int keyCode = event.getKeyCode();
@@ -3197,14 +3153,17 @@
                                                 mKeyguardMediator.isShowingAndNotHidden() :
                                                 mKeyguardMediator.isShowing()));
 
-        if (!mSystemBooted) {
-            // If we have not yet booted, don't let key events do anything.
-            return 0;
+        if (keyCode == KeyEvent.KEYCODE_POWER) {
+            policyFlags |= WindowManagerPolicy.FLAG_WAKE;
         }
+        final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
+                | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
 
         if (DEBUG_INPUT) {
             Log.d(TAG, "interceptKeyTq keycode=" + keyCode
-                  + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
+                    + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive
+                    + " policyFlags=" + Integer.toHexString(policyFlags)
+                    + " isWakeKey=" + isWakeKey);
         }
 
         if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
@@ -3212,12 +3171,6 @@
             performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
         }
 
-        if (keyCode == KeyEvent.KEYCODE_POWER) {
-            policyFlags |= WindowManagerPolicy.FLAG_WAKE;
-        }
-        final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
-                | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
-
         // Basic policy based on screen state and keyguard.
         // FIXME: This policy isn't quite correct.  We shouldn't care whether the screen
         //        is on or off, really.  We should care about whether the device is in an
@@ -3241,7 +3194,7 @@
                             mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
                 } else {
                     // Otherwise, wake the device ourselves.
-                    result |= ACTION_POKE_USER_ACTIVITY;
+                    result |= ACTION_WAKE_UP;
                 }
             }
         }
@@ -3346,7 +3299,7 @@
                         }
                         if ((mEndcallBehavior
                                 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
-                            result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
+                            result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
                         }
                     }
                 }
@@ -3388,7 +3341,7 @@
                     mPowerKeyTriggered = false;
                     cancelPendingScreenshotChordAction();
                     if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
-                        result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
+                        result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
                     }
                     mPendingPowerKeyUpCanceled = false;
                 }
@@ -3473,7 +3426,7 @@
                 mKeyguardMediator.onWakeMotionWhenKeyguardShowingTq();
             } else {
                 // Otherwise, wake the device ourselves.
-                result |= ACTION_POKE_USER_ACTIVITY;
+                result |= ACTION_WAKE_UP;
             }
         }
         return result;
@@ -3553,15 +3506,6 @@
         }
     };
 
-    BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
-                mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
-                if (localLOGV) Log.v(TAG, "BATTERY_CHANGED: " + intent + " plugged=" + mPluggedIn);
-            }
-        }
-    };
-
     /** {@inheritDoc} */
     public void screenTurnedOff(int why) {
         EventLog.writeEvent(70000, 0);
@@ -4035,62 +3979,6 @@
         }
     }
 
-    private IDreamManager getDreamManager() {
-        if (!mScreenSaverFeatureAvailable) {
-            return null;
-        }
-        
-        IDreamManager sandman = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService("dreams"));
-        if (sandman == null) {
-            Log.w(TAG, "Unable to find IDreamManager");
-        }
-        return sandman;
-    }
-
-    @Override
-    public boolean isScreenSaverEnabled() {
-        return (mScreenSaverFeatureAvailable && mScreenSaverEnabledByUser
-                && mScreenSaverMayRun && mScreenOnEarly && mPluggedIn);
-    }
-
-    @Override
-    public boolean startScreenSaver() {
-        synchronized (mLock) {
-            if (isScreenSaverEnabled()) {
-                IDreamManager dm = getDreamManager();
-                if (dm == null) return false;
-                
-                try {
-                    if (localLOGV) Log.v(TAG, "startScreenSaver: entering dreamland...");
-
-                    dm.dream();
-                    return true;
-                } catch (RemoteException ex) {
-                    // too bad, so sad, oh mom, oh dad
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void stopScreenSaver() {
-        synchronized (mLock) {
-            IDreamManager dm = getDreamManager();
-            if (dm == null) return;
-            
-            try {
-                if (!dm.isDreaming()) return;
-
-                if (localLOGV) Log.v(TAG, "stopScreenSaver: awakening...");
-                
-                dm.awaken();
-            } catch (RemoteException ex) {
-            }
-        }
-    }
-
     Runnable mScreenLockTimeout = new Runnable() {
         public void run() {
             synchronized (this) {
@@ -4134,8 +4022,6 @@
     }
 
     private void applyLidSwitchState() {
-        mPowerManager.setKeyboardVisibility(isBuiltInKeyboardVisible());
-
         if (mLidState == LID_CLOSED && mLidControlsSleep) {
             mPowerManager.goToSleep(SystemClock.uptimeMillis());
         }
@@ -4317,24 +4203,13 @@
     }
     
     public void screenOnStartedLw() {
-        // The window manager has just grabbed a wake lock. This is our cue to disable the screen
-        // saver.
-        synchronized (mLock) {
-            mScreenSaverMayRun = false;
-        }
     }
 
     public void screenOnStoppedLw() {
         if (mPowerManager.isScreenOn()) {
             if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
                 long curTime = SystemClock.uptimeMillis();
-                mPowerManager.userActivity(curTime, false, PowerManager.USER_ACTIVITY_EVENT_OTHER);
-            }
-
-            synchronized (mLock) {
-                // even if the keyguard is up, now that all the wakelocks have been released, we
-                // should re-enable the screen saver
-                mScreenSaverMayRun = true;
+                mPowerManager.userActivity(curTime, false);
             }
         }
     }
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index ea19d6e..f966a33 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1626,7 +1626,7 @@
             mLastMaximumTimeToLock = timeMs;
 
             try {
-                getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
+                getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failure talking with power manager", e);
             }
@@ -1667,8 +1667,8 @@
             long ident = Binder.clearCallingIdentity();
             try {
                 // Power off the display
-                mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(),
-                        WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN);
+                getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
+                        PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN);
                 // Ensure the device is locked
                 getWindowManager().lockNow();
             } catch (RemoteException e) {
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 6f050d3..8bdd7be 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -33,6 +33,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UEventObserver;
 import android.provider.Settings;
@@ -64,11 +65,8 @@
 
     private final Context mContext;
 
-    private PowerManagerService mPowerManager;
-
-    public DockObserver(Context context, PowerManagerService pm) {
+    public DockObserver(Context context) {
         mContext = context;
-        mPowerManager = pm;
         init();  // set initial status
 
         startObserving(DOCK_UEVENT_MATCH);
@@ -94,8 +92,9 @@
                                 && mPreviousDockState != Intent.EXTRA_DOCK_STATE_LE_DESK
                                 && mPreviousDockState != Intent.EXTRA_DOCK_STATE_HE_DESK) ||
                                 mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                            mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(),
-                                    false, true);
+                            PowerManager pm =
+                                    (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+                            pm.wakeUp(SystemClock.uptimeMillis());
                         }
                         update();
                     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e8350c1..c471dd2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -50,6 +50,7 @@
 import com.android.internal.widget.LockSettingsService;
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.am.ActivityManagerService;
+import com.android.server.am.BatteryStatsService;
 import com.android.server.display.DisplayManagerService;
 import com.android.server.input.InputManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
@@ -230,7 +231,8 @@
 
             // only initialize the power service after we have started the
             // lights service, content providers and the battery service.
-            power.init(context, lights, ActivityManagerService.self(), battery, display);
+            power.init(context, lights, ActivityManagerService.self(), battery,
+                    BatteryStatsService.getService(), display);
 
             Slog.i(TAG, "Alarm Manager");
             alarm = new AlarmManagerService(context);
@@ -553,7 +555,7 @@
             try {
                 Slog.i(TAG, "Dock Observer");
                 // Listen for dock station changes
-                dock = new DockObserver(context, power);
+                dock = new DockObserver(context);
             } catch (Throwable e) {
                 reportWtf("starting DockObserver", e);
             }
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index c5b4a07..9edfad6 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -349,7 +349,7 @@
         }
 
         if (mMinScreenOff >= 0 && (mPower == null ||
-                mPower.timeSinceScreenOn() < mMinScreenOff)) {
+                mPower.timeSinceScreenWasLastOn() < mMinScreenOff)) {
             return "screen";
         }
 
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
new file mode 100644
index 0000000..50d3f81
--- /dev/null
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -0,0 +1,992 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import com.android.server.LightsService;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.SystemSensorManager;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.util.TimeUtils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+
+/**
+ * Controls the power state of the display.
+ *
+ * Handles the proximity sensor, light sensor, and animations between states
+ * including the screen off animation.
+ *
+ * This component acts independently of the rest of the power manager service.
+ * In particular, it does not share any state and it only communicates
+ * via asynchronous callbacks to inform the power manager that something has
+ * changed.
+ *
+ * Everything this class does internally is serialized on its handler although
+ * it may be accessed by other threads from the outside.
+ *
+ * Note that the power manager service guarantees that it will hold a suspend
+ * blocker as long as the display is not ready.  So most of the work done here
+ * does not need to worry about holding a suspend blocker unless it happens
+ * independently of the display ready signal.
+ *
+ * For debugging, you can make the electron beam and brightness animations run
+ * slower by changing the "animator duration scale" option in Development Settings.
+ */
+final class DisplayPowerController {
+    private static final String TAG = "DisplayPowerController";
+
+    private static boolean DEBUG = false;
+    private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
+    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
+
+    private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 300;
+    private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 600;
+
+    private static final int MSG_UPDATE_POWER_STATE = 1;
+    private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
+    private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
+
+    private static final int PROXIMITY_UNKNOWN = -1;
+    private static final int PROXIMITY_NEGATIVE = 0;
+    private static final int PROXIMITY_POSITIVE = 1;
+
+    // Proximity sensor debounce delay in milliseconds.
+    private static final int PROXIMITY_SENSOR_DEBOUNCE_DELAY = 250;
+
+    // Trigger proximity if distance is less than 5 cm.
+    private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
+
+    // Light sensor event rate in microseconds.
+    private static final int LIGHT_SENSOR_RATE = 1000000;
+
+    // Brightness animation ramp rate in brightness units per second.
+    private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
+    private static final int BRIGHTNESS_RAMP_RATE_SLOW = 50;
+
+    // Filter time constant in milliseconds for computing a moving
+    // average of light samples.  Different constants are used
+    // to adapt to brighter or dimmer environments.
+    private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 2500; // 2.5 sec
+    private static final long DIMMING_LIGHT_TIME_CONSTANT = 10000; // 10 sec
+
+    private final Object mLock = new Object();
+
+    // Notifier for sending asynchronous notifications.
+    private final Notifier mNotifier;
+
+    // A suspend blocker.
+    private final SuspendBlocker mSuspendBlocker;
+
+    // Our handler.
+    private final DisplayControllerHandler mHandler;
+
+    // Asynchronous callbacks into the power manager service.
+    // Only invoked from the handler thread while no locks are held.
+    private final Callbacks mCallbacks;
+    private Handler mCallbackHandler;
+
+    // The lights service.
+    private final LightsService mLights;
+
+    // The sensor manager.
+    private final SensorManager mSensorManager;
+
+    // The proximity sensor, or null if not available or needed.
+    private Sensor mProximitySensor;
+
+    // The light sensor, or null if not available or needed.
+    private Sensor mLightSensor;
+
+    // The dim screen brightness.
+    private final int mScreenBrightnessDimConfig;
+
+    // Auto-brightness.
+    private boolean mUseSoftwareAutoBrightnessConfig;
+    private int[] mAutoBrightnessLevelsConfig;
+    private int[] mAutoBrightnessLcdBacklightValuesConfig;
+
+    // Amount of time to delay auto-brightness after screen on while waiting for
+    // the light sensor to warm-up in milliseconds.
+    // May be 0 if no warm-up is required.
+    private int mLightSensorWarmUpTimeConfig;
+
+    // The pending power request.
+    // Initially null until the first call to requestPowerState.
+    // Guarded by mLock.
+    private DisplayPowerRequest mPendingRequestLocked;
+
+    // True if a request has been made to wait for the proximity sensor to go negative.
+    // Guarded by mLock.
+    private boolean mPendingWaitForNegativeProximityLocked;
+
+    // True if the pending power request or wait for negative proximity flag
+    // has been changed since the last update occurred.
+    // Guarded by mLock.
+    private boolean mPendingRequestChangedLocked;
+
+    // Set to true when the important parts of the pending power request have been applied.
+    // The important parts are mainly the screen state.  Brightness changes may occur
+    // concurrently.
+    // Guarded by mLock.
+    private boolean mDisplayReadyLocked;
+
+    // Set to true if a power state update is required.
+    // Guarded by mLock.
+    private boolean mPendingUpdatePowerStateLocked;
+
+    /* The following state must only be accessed by the handler thread. */
+
+    // The currently requested power state.
+    // The power controller will progressively update its internal state to match
+    // the requested power state.  Initially null until the first update.
+    private DisplayPowerRequest mPowerRequest;
+
+    // The current power state.
+    // Must only be accessed on the handler thread.
+    private DisplayPowerState mPowerState;
+
+    // True if the device should wait for negative proximity sensor before
+    // waking up the screen.  This is set to false as soon as a negative
+    // proximity sensor measurement is observed or when the device is forced to
+    // go to sleep by the user.  While true, the screen remains off.
+    private boolean mWaitingForNegativeProximity;
+
+    // The actual proximity sensor threshold value.
+    private float mProximityThreshold;
+
+    // Set to true if the proximity sensor listener has been registered
+    // with the sensor manager.
+    private boolean mProximitySensorEnabled;
+
+    // The debounced proximity sensor state.
+    private int mProximity = PROXIMITY_UNKNOWN;
+
+    // The raw non-debounced proximity sensor state.
+    private int mPendingProximity = PROXIMITY_UNKNOWN;
+    private long mPendingProximityDebounceTime;
+
+    // True if the screen was turned off because of the proximity sensor.
+    // When the screen turns on again, we report user activity to the power manager.
+    private boolean mScreenOffBecauseOfProximity;
+
+    // Set to true if the light sensor is enabled.
+    private boolean mLightSensorEnabled;
+
+    // The time when the light sensor was enabled.
+    private long mLightSensorEnableTime;
+
+    // The currently accepted average light sensor value.
+    private float mLightMeasurement;
+
+    // True if the light sensor measurement is valid.
+    private boolean mLightMeasurementValid;
+
+    // The number of light sensor samples that have been collected since the
+    // last time a light sensor reading was accepted.
+    private int mRecentLightSamples;
+
+    // The moving average of recent light sensor values.
+    private float mRecentLightAverage;
+
+    // True if recent light samples are getting brighter than the previous
+    // stable light measurement.
+    private boolean mRecentLightBrightening;
+
+    // The time constant to use for filtering based on whether the
+    // light appears to be brightening or dimming.
+    private long mRecentLightTimeConstant;
+
+    // The most recent light sample.
+    private float mLastLightSample;
+
+    // The time of the most light recent sample.
+    private long mLastLightSampleTime;
+
+    // The upcoming debounce light sensor time.
+    // This is only valid when mLightMeasurementValue && mRecentLightSamples >= 1.
+    private long mPendingLightSensorDebounceTime;
+
+    // The screen brightness level that has been chosen by the auto-brightness
+    // algorithm.  The actual brightness should ramp towards this value.
+    // We preserve this value even when we stop using the light sensor so
+    // that we can quickly revert to the previous auto-brightness level
+    // while the light sensor warms up.
+    // Use -1 if there is no current auto-brightness value available.
+    private int mScreenAutoBrightness = -1;
+
+    // True if the screen auto-brightness value is actually being used to
+    // set the display brightness.
+    private boolean mUsingScreenAutoBrightness;
+
+    // Animators.
+    private ObjectAnimator mElectronBeamOnAnimator;
+    private ObjectAnimator mElectronBeamOffAnimator;
+    private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
+
+    /**
+     * Creates the display power controller.
+     */
+    public DisplayPowerController(Looper looper, Context context, Notifier notifier,
+            LightsService lights, SuspendBlocker suspendBlocker,
+            Callbacks callbacks, Handler callbackHandler) {
+        mHandler = new DisplayControllerHandler(looper);
+        mNotifier = notifier;
+        mSuspendBlocker = suspendBlocker;
+        mCallbacks = callbacks;
+        mCallbackHandler = callbackHandler;
+
+        mLights = lights;
+        mSensorManager = new SystemSensorManager(mHandler.getLooper());
+
+        final Resources resources = context.getResources();
+        mScreenBrightnessDimConfig = resources.getInteger(
+                com.android.internal.R.integer.config_screenBrightnessDim);
+        mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_automatic_brightness_available);
+        if (mUseSoftwareAutoBrightnessConfig) {
+            mAutoBrightnessLevelsConfig = resources.getIntArray(
+                    com.android.internal.R.array.config_autoBrightnessLevels);
+            mAutoBrightnessLcdBacklightValuesConfig = resources.getIntArray(
+                    com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+            if (mAutoBrightnessLcdBacklightValuesConfig.length
+                    != mAutoBrightnessLevelsConfig.length + 1) {
+                Slog.e(TAG, "Error in config.xml.  config_autoBrightnessLcdBacklightValues "
+                        + "(size " + mAutoBrightnessLcdBacklightValuesConfig.length + ") "
+                        + "should have exactly one more entry than "
+                        + "config_autoBrightnessLevels (size "
+                        + mAutoBrightnessLevelsConfig.length + ").  "
+                        + "Auto-brightness will be disabled.");
+                mUseSoftwareAutoBrightnessConfig = false;
+            }
+
+            mLightSensorWarmUpTimeConfig = resources.getInteger(
+                    com.android.internal.R.integer.config_lightSensorWarmupTime);
+        }
+
+        if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
+            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+            if (mProximitySensor != null) {
+                mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
+                        TYPICAL_PROXIMITY_THRESHOLD);
+            }
+        }
+
+        if (mUseSoftwareAutoBrightnessConfig
+                && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
+            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+        }
+    }
+
+    /**
+     * Returns true if the proximity sensor screen-off function is available.
+     */
+    public boolean isProximitySensorAvailable() {
+        return mProximitySensor != null;
+    }
+
+    /**
+     * Requests a new power state.
+     * The controller makes a copy of the provided object and then
+     * begins adjusting the power state to match what was requested.
+     *
+     * @param request The requested power state.
+     * @param waitForNegativeProximity If true, issues a request to wait for
+     * negative proximity before turning the screen back on, assuming the screen
+     * was turned off by the proximity sensor.
+     * @return True if display is ready, false if there are important changes that must
+     * be made asynchronously (such as turning the screen on), in which case the caller
+     * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try
+     * the request again later until the state converges.
+     */
+    public boolean requestPowerState(DisplayPowerRequest request,
+            boolean waitForNegativeProximity) {
+        if (DEBUG) {
+            Slog.d(TAG, "requestPowerState: "
+                    + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
+        }
+
+        synchronized (mLock) {
+            boolean changed = false;
+
+            if (waitForNegativeProximity
+                    && !mPendingWaitForNegativeProximityLocked) {
+                mPendingWaitForNegativeProximityLocked = true;
+                changed = true;
+            }
+
+            if (mPendingRequestLocked == null) {
+                mPendingRequestLocked = new DisplayPowerRequest(request);
+                changed = true;
+            } else if (!mPendingRequestLocked.equals(request)) {
+                mPendingRequestLocked.copyFrom(request);
+                changed = true;
+            }
+
+            if (changed) {
+                mDisplayReadyLocked = false;
+            }
+
+            if (changed && !mPendingRequestChangedLocked) {
+                mPendingRequestChangedLocked = true;
+                sendUpdatePowerStateLocked();
+            }
+
+            return mDisplayReadyLocked;
+        }
+    }
+
+    private void sendUpdatePowerState() {
+        synchronized (mLock) {
+            sendUpdatePowerStateLocked();
+        }
+    }
+
+    private void sendUpdatePowerStateLocked() {
+        if (!mPendingUpdatePowerStateLocked) {
+            mPendingUpdatePowerStateLocked = true;
+            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
+            msg.setAsynchronous(true);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    private void initialize() {
+        final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
+        mPowerState = new DisplayPowerState(new ElectronBeam(),
+                new PhotonicModulator(executor,
+                        mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
+                        mSuspendBlocker));
+
+        mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
+                mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);
+        mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS);
+        mElectronBeamOnAnimator.addListener(mAnimatorListener);
+
+        mElectronBeamOffAnimator = ObjectAnimator.ofFloat(
+                mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f);
+        mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS);
+        mElectronBeamOffAnimator.addListener(mAnimatorListener);
+
+        mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
+                mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
+    }
+
+    private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
+        @Override
+        public void onAnimationStart(Animator animation) {
+        }
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            sendUpdatePowerState();
+        }
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+        }
+        @Override
+        public void onAnimationCancel(Animator animation) {
+        }
+    };
+
+    private void updatePowerState() {
+        // Update the power state request.
+        final boolean mustNotify;
+        boolean mustInitialize = false;
+        synchronized (mLock) {
+            mPendingUpdatePowerStateLocked = false;
+            if (mPendingRequestLocked == null) {
+                return; // wait until first actual power request
+            }
+
+            if (mPowerRequest == null) {
+                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
+                mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
+                mPendingRequestChangedLocked = false;
+                mustInitialize = true;
+            } else if (mPendingRequestChangedLocked) {
+                mPowerRequest.copyFrom(mPendingRequestLocked);
+                mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
+                mPendingRequestChangedLocked = false;
+                mDisplayReadyLocked = false;
+            }
+
+            mustNotify = !mDisplayReadyLocked;
+        }
+
+        // Initialize things the first time the power state is changed.
+        if (mustInitialize) {
+            initialize();
+        }
+
+        // Clear a request to wait for negative proximity if needed.
+        if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_OFF
+                || mProximity == PROXIMITY_NEGATIVE
+                || mProximitySensor == null) {
+            mWaitingForNegativeProximity = false;
+        }
+
+        // Turn on the proximity sensor if needed.
+        if (mProximitySensor != null) {
+            setProximitySensorEnabled(mPowerRequest.useProximitySensor
+                    || mWaitingForNegativeProximity);
+            if (mProximitySensorEnabled && mProximity == PROXIMITY_POSITIVE) {
+                mScreenOffBecauseOfProximity = true;
+                setScreenOn(false);
+            } else if (mScreenOffBecauseOfProximity) {
+                mScreenOffBecauseOfProximity = false;
+                sendOnProximityNegative();
+            }
+        }
+
+        // Turn on the light sensor if needed.
+        if (mLightSensor != null) {
+            setLightSensorEnabled(mPowerRequest.useAutoBrightness
+                    && wantScreenOn(mPowerRequest.screenState));
+        }
+
+        // Set the screen brightness.
+        if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
+            // Screen is dimmed.  Overrides everything else.
+            animateScreenBrightness(mScreenBrightnessDimConfig, BRIGHTNESS_RAMP_RATE_FAST);
+            mUsingScreenAutoBrightness = false;
+        } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT) {
+            if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
+                // Use current auto-brightness value.
+                animateScreenBrightness(
+                        Math.max(mScreenAutoBrightness, mScreenBrightnessDimConfig),
+                        mUsingScreenAutoBrightness ? BRIGHTNESS_RAMP_RATE_SLOW :
+                                BRIGHTNESS_RAMP_RATE_FAST);
+                mUsingScreenAutoBrightness = true;
+            } else {
+                // Light sensor is disabled or not ready yet.
+                // Use the current brightness setting from the request, which is expected
+                // provide a nominal default value for the case where auto-brightness
+                // is not ready yet.
+                animateScreenBrightness(
+                        Math.max(mPowerRequest.screenBrightness, mScreenBrightnessDimConfig),
+                        BRIGHTNESS_RAMP_RATE_FAST);
+                mUsingScreenAutoBrightness = false;
+            }
+        } else {
+            // Screen is off.  Don't bother changing the brightness.
+            mUsingScreenAutoBrightness = false;
+        }
+
+        // Animate the screen on or off.
+        if (!mScreenOffBecauseOfProximity) {
+            if (wantScreenOn(mPowerRequest.screenState)) {
+                // Want screen on.
+                // Wait for previous off animation to complete beforehand.
+                // It is relatively short but if we cancel it and switch to the
+                // on animation immediately then the results are pretty ugly.
+                if (!mElectronBeamOffAnimator.isStarted()) {
+                    setScreenOn(true);
+                    if (!mElectronBeamOnAnimator.isStarted()) {
+                        if (mPowerState.getElectronBeamLevel() == 1.0f) {
+                            mPowerState.dismissElectronBeam();
+                        } else if (mPowerState.prepareElectronBeam(true)) {
+                            mElectronBeamOnAnimator.start();
+                        } else {
+                            mElectronBeamOnAnimator.end();
+                        }
+                    }
+                }
+            } else {
+                // Want screen off.
+                // Wait for previous on animation to complete beforehand.
+                if (!mElectronBeamOnAnimator.isStarted()) {
+                    if (!mElectronBeamOffAnimator.isStarted()) {
+                        if (mPowerState.getElectronBeamLevel() == 0.0f) {
+                            setScreenOn(false);
+                        } else if (mPowerState.prepareElectronBeam(false)
+                                && mPowerState.isScreenOn()) {
+                            mElectronBeamOffAnimator.start();
+                        } else {
+                            mElectronBeamOffAnimator.end();
+                        }
+                    }
+                }
+            }
+        }
+
+        // Report whether the display is ready for use.
+        // We mostly care about the screen state here, ignoring brightness changes
+        // which will be handled asynchronously.
+        if (mustNotify
+                && !mElectronBeamOnAnimator.isStarted()
+                && !mElectronBeamOffAnimator.isStarted()
+                && mPowerState.waitUntilClean(mCleanListener)) {
+            synchronized (mLock) {
+                if (!mPendingRequestChangedLocked) {
+                    mDisplayReadyLocked = true;
+                }
+            }
+            sendOnStateChanged();
+        }
+    }
+
+    private void setScreenOn(boolean on) {
+        if (!mPowerState.isScreenOn() == on) {
+            mPowerState.setScreenOn(on);
+            if (on) {
+                mNotifier.onScreenOn();
+            } else {
+                mNotifier.onScreenOff();
+            }
+        }
+    }
+
+    private void animateScreenBrightness(int target, int rate) {
+        if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
+            mNotifier.onScreenBrightness(target);
+        }
+    }
+
+    private final Runnable mCleanListener = new Runnable() {
+        @Override
+        public void run() {
+            sendUpdatePowerState();
+        }
+    };
+
+    private void setProximitySensorEnabled(boolean enable) {
+        if (enable) {
+            if (!mProximitySensorEnabled) {
+                mProximitySensorEnabled = true;
+                mPendingProximity = PROXIMITY_UNKNOWN;
+                mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
+                        SensorManager.SENSOR_DELAY_NORMAL, mHandler);
+            }
+        } else {
+            if (mProximitySensorEnabled) {
+                mProximitySensorEnabled = false;
+                mProximity = PROXIMITY_UNKNOWN;
+                mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
+                mSensorManager.unregisterListener(mProximitySensorListener);
+            }
+        }
+    }
+
+    private void handleProximitySensorEvent(long time, boolean positive) {
+        if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
+            return; // no change
+        }
+        if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
+            return; // no change
+        }
+
+        // Only accept a proximity sensor reading if it remains
+        // stable for the entire debounce delay.
+        mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
+        mPendingProximity = positive ? PROXIMITY_POSITIVE : PROXIMITY_NEGATIVE;
+        mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_DEBOUNCE_DELAY;
+        debounceProximitySensor();
+    }
+
+    private void debounceProximitySensor() {
+        if (mPendingProximity != PROXIMITY_UNKNOWN) {
+            final long now = SystemClock.uptimeMillis();
+            if (mPendingProximityDebounceTime <= now) {
+                mProximity = mPendingProximity;
+                sendUpdatePowerState();
+            } else {
+                Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
+                msg.setAsynchronous(true);
+                mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
+            }
+        }
+    }
+
+    private void setLightSensorEnabled(boolean enable) {
+        if (enable) {
+            if (!mLightSensorEnabled) {
+                mLightSensorEnabled = true;
+                mLightSensorEnableTime = SystemClock.uptimeMillis();
+                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
+                        LIGHT_SENSOR_RATE, mHandler);
+            }
+        } else {
+            if (mLightSensorEnabled) {
+                mLightSensorEnabled = false;
+                mLightMeasurementValid = false;
+                updateAutoBrightness(false);
+                mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+    }
+
+    private void handleLightSensorEvent(long time, float lux) {
+        // Take the first few readings during the warm-up period and apply them
+        // immediately without debouncing.
+        if (!mLightMeasurementValid
+                || (time - mLightSensorEnableTime) < mLightSensorWarmUpTimeConfig) {
+            mLightMeasurement = lux;
+            mLightMeasurementValid = true;
+            mRecentLightSamples = 0;
+            updateAutoBrightness(true);
+        }
+
+        // Update our moving average.
+        if (lux != mLightMeasurement && (mRecentLightSamples == 0
+                || (lux < mLightMeasurement && mRecentLightBrightening)
+                || (lux > mLightMeasurement && !mRecentLightBrightening))) {
+            // If the newest light sample doesn't seem to be going in the
+            // same general direction as recent samples, then start over.
+            setRecentLight(time, lux, lux > mLightMeasurement);
+            mPendingLightSensorDebounceTime = time + mRecentLightTimeConstant;
+        } else if (mRecentLightSamples >= 1) {
+            // Add the newest light sample to the moving average.
+            accumulateRecentLight(time, lux);
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "handleLightSensorEvent: lux=" + lux
+                    + ", mLightMeasurementValid=" + mLightMeasurementValid
+                    + ", mLightMeasurement=" + mLightMeasurement
+                    + ", mRecentLightSamples=" + mRecentLightSamples
+                    + ", mRecentLightAverage=" + mRecentLightAverage
+                    + ", mRecentLightBrightening=" + mRecentLightBrightening
+                    + ", mRecentLightTimeConstant=" + mRecentLightTimeConstant
+                    + ", mPendingLightSensorDebounceTime="
+                            + TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
+        }
+
+        // Debounce.
+        mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
+        debounceLightSensor();
+    }
+
+    private void setRecentLight(long time, float lux, boolean brightening) {
+        mRecentLightBrightening = brightening;
+        mRecentLightTimeConstant = brightening ?
+                BRIGHTENING_LIGHT_TIME_CONSTANT : DIMMING_LIGHT_TIME_CONSTANT;
+        mRecentLightSamples = 1;
+        mRecentLightAverage = lux;
+        mLastLightSample = lux;
+        mLastLightSampleTime = time;
+    }
+
+    private void accumulateRecentLight(long time, float lux) {
+        final long timeDelta = time - mLastLightSampleTime;
+        mRecentLightSamples += 1;
+        mRecentLightAverage += (lux - mRecentLightAverage) *
+                timeDelta / (mRecentLightTimeConstant + timeDelta);
+        mLastLightSample = lux;
+        mLastLightSampleTime = time;
+    }
+
+    private void debounceLightSensor() {
+        if (mLightMeasurementValid && mRecentLightSamples >= 1) {
+            final long now = SystemClock.uptimeMillis();
+            if (mPendingLightSensorDebounceTime <= now) {
+                accumulateRecentLight(now, mLastLightSample);
+                mLightMeasurement = mRecentLightAverage;
+
+                if (DEBUG) {
+                    Slog.d(TAG, "debounceLightSensor: Accepted new measurement "
+                            + mLightMeasurement + " after "
+                            + (now - mPendingLightSensorDebounceTime
+                                    + mRecentLightTimeConstant) + " ms based on "
+                            + mRecentLightSamples + " recent samples.");
+                }
+
+                updateAutoBrightness(true);
+
+                // Now that we have debounced the light sensor data, we have the
+                // option of either leaving the sensor in a debounced state or
+                // restarting the debounce cycle by setting mRecentLightSamples to 0.
+                //
+                // If we leave the sensor debounced, then new average light measurements
+                // may be accepted immediately as long as they are trending in the same
+                // direction as they were before.  If the measurements start
+                // jittering or trending in the opposite direction then the debounce
+                // cycle will automatically be restarted.  The benefit is that the
+                // auto-brightness control can be more responsive to changes over a
+                // broad range.
+                //
+                // For now, we choose to be more responsive and leave the following line
+                // commented out.
+                //
+                // mRecentLightSamples = 0;
+            } else {
+                Message msg = mHandler.obtainMessage(MSG_LIGHT_SENSOR_DEBOUNCED);
+                msg.setAsynchronous(true);
+                mHandler.sendMessageAtTime(msg, mPendingLightSensorDebounceTime);
+            }
+        }
+    }
+
+    private void updateAutoBrightness(boolean sendUpdate) {
+        if (!mLightMeasurementValid) {
+            return;
+        }
+
+        final int newScreenAutoBrightness = mapLuxToBrightness(mLightMeasurement,
+                mAutoBrightnessLevelsConfig,
+                mAutoBrightnessLcdBacklightValuesConfig);
+        if (mScreenAutoBrightness != newScreenAutoBrightness) {
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
+                        + mScreenAutoBrightness);
+            }
+
+            mScreenAutoBrightness = newScreenAutoBrightness;
+            if (sendUpdate) {
+                sendUpdatePowerState();
+            }
+        }
+    }
+
+    /**
+     * Maps a light sensor measurement in lux to a brightness value given
+     * a table of lux breakpoint values and a table of brightnesses that
+     * is one element larger.
+     */
+    private static int mapLuxToBrightness(float lux,
+            int[] fromLux, int[] toBrightness) {
+        // TODO implement interpolation and possibly range expansion
+        int level = 0;
+        final int count = fromLux.length;
+        while (level < count && lux >= fromLux[level]) {
+            level += 1;
+        }
+        return toBrightness[level];
+    }
+
+    private void sendOnStateChanged() {
+        mCallbackHandler.post(mOnStateChangedRunnable);
+    }
+
+    private final Runnable mOnStateChangedRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mCallbacks.onStateChanged();
+        }
+    };
+
+    private void sendOnProximityNegative() {
+        mCallbackHandler.post(mOnProximityNegativeRunnable);
+    }
+
+    private final Runnable mOnProximityNegativeRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mCallbacks.onProximityNegative();
+        }
+    };
+
+    public void dump(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println();
+            pw.println("Display Controller Locked State:");
+            pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
+            pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
+            pw.println("  mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
+            pw.println("  mPendingWaitForNegativeProximityLocked="
+                    + mPendingWaitForNegativeProximityLocked);
+            pw.println("  mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
+        }
+
+        pw.println();
+        pw.println("Display Controller Configuration:");
+        pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
+        pw.println("  mUseSoftwareAutoBrightnessConfig="
+                + mUseSoftwareAutoBrightnessConfig);
+        pw.println("  mAutoBrightnessLevelsConfig="
+                + Arrays.toString(mAutoBrightnessLevelsConfig));
+        pw.println("  mAutoBrightnessLcdBacklightValuesConfig="
+                + Arrays.toString(mAutoBrightnessLcdBacklightValuesConfig));
+        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
+
+        if (Looper.myLooper() == mHandler.getLooper()) {
+            dumpLocal(pw);
+        } else {
+            final StringWriter out = new StringWriter();
+            final CountDownLatch latch = new CountDownLatch(1);
+            Message msg = Message.obtain(mHandler,  new Runnable() {
+                @Override
+                public void run() {
+                    PrintWriter localpw = new PrintWriter(out);
+                    try {
+                        dumpLocal(localpw);
+                    } finally {
+                        localpw.flush();
+                        latch.countDown();
+                    }
+                }
+            });
+            msg.setAsynchronous(true);
+            mHandler.sendMessage(msg);
+            try {
+                latch.await();
+                pw.print(out.toString());
+            } catch (InterruptedException ex) {
+                pw.println();
+                pw.println("Failed to dump thread state due to interrupted exception!");
+            }
+        }
+    }
+
+    private void dumpLocal(PrintWriter pw) {
+        pw.println();
+        pw.println("Display Controller Thread State:");
+        pw.println("  mPowerRequest=" + mPowerRequest);
+        pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
+
+        pw.println("  mProximitySensor=" + mProximitySensor);
+        pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
+        pw.println("  mProximityThreshold=" + mProximityThreshold);
+        pw.println("  mProximity=" + proximityToString(mProximity));
+        pw.println("  mPendingProximity=" + proximityToString(mPendingProximity));
+        pw.println("  mPendingProximityDebounceTime="
+                + TimeUtils.formatUptime(mPendingProximityDebounceTime));
+        pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
+
+        pw.println("  mLightSensor=" + mLightSensor);
+        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
+        pw.println("  mLightSensorEnableTime="
+                + TimeUtils.formatUptime(mLightSensorEnableTime));
+        pw.println("  mLightMeasurement=" + mLightMeasurement);
+        pw.println("  mLightMeasurementValid=" + mLightMeasurementValid);
+        pw.println("  mLastLightSample=" + mLastLightSample);
+        pw.println("  mLastLightSampleTime="
+                + TimeUtils.formatUptime(mLastLightSampleTime));
+        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
+        pw.println("  mRecentLightAverage=" + mRecentLightAverage);
+        pw.println("  mRecentLightBrightening=" + mRecentLightBrightening);
+        pw.println("  mRecentLightTimeConstant=" + mRecentLightTimeConstant);
+        pw.println("  mPendingLightSensorDebounceTime="
+                + TimeUtils.formatUptime(mPendingLightSensorDebounceTime));
+        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
+        pw.println("  mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
+
+        if (mElectronBeamOnAnimator != null) {
+            pw.println("  mElectronBeamOnAnimator.isStarted()=" +
+                    mElectronBeamOnAnimator.isStarted());
+        }
+        if (mElectronBeamOffAnimator != null) {
+            pw.println("  mElectronBeamOffAnimator.isStarted()=" +
+                    mElectronBeamOffAnimator.isStarted());
+        }
+
+        if (mPowerState != null) {
+            mPowerState.dump(pw);
+        }
+    }
+
+    private static String proximityToString(int state) {
+        switch (state) {
+            case PROXIMITY_UNKNOWN:
+                return "Unknown";
+            case PROXIMITY_NEGATIVE:
+                return "Negative";
+            case PROXIMITY_POSITIVE:
+                return "Positive";
+            default:
+                return Integer.toString(state);
+        }
+    }
+
+    private static boolean wantScreenOn(int state) {
+        switch (state) {
+            case DisplayPowerRequest.SCREEN_STATE_BRIGHT:
+            case DisplayPowerRequest.SCREEN_STATE_DIM:
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Asynchronous callbacks from the power controller to the power manager service.
+     */
+    public interface Callbacks {
+        void onStateChanged();
+        void onProximityNegative();
+    }
+
+    private final class DisplayControllerHandler extends Handler {
+        public DisplayControllerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_POWER_STATE:
+                    updatePowerState();
+                    break;
+
+                case MSG_PROXIMITY_SENSOR_DEBOUNCED:
+                    debounceProximitySensor();
+                    break;
+
+                case MSG_LIGHT_SENSOR_DEBOUNCED:
+                    debounceLightSensor();
+                    break;
+            }
+        }
+    }
+
+    private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            if (mProximitySensorEnabled) {
+                final long time = SystemClock.uptimeMillis();
+                final float distance = event.values[0];
+                boolean positive = distance >= 0.0f && distance < mProximityThreshold;
+                handleProximitySensorEvent(time, positive);
+            }
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // Not used.
+        }
+    };
+
+    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            if (mLightSensorEnabled) {
+                final long time = SystemClock.uptimeMillis();
+                final float lux = event.values[0];
+                handleLightSensorEvent(time, lux);
+            }
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // Not used.
+        }
+    };
+}
diff --git a/services/java/com/android/server/power/DisplayPowerRequest.java b/services/java/com/android/server/power/DisplayPowerRequest.java
new file mode 100644
index 0000000..7e4607e
--- /dev/null
+++ b/services/java/com/android/server/power/DisplayPowerRequest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.os.PowerManager;
+
+/**
+ * Describes the requested power state of the display.
+ *
+ * This object is intended to describe the general characteristics of the
+ * power state, such as whether the screen should be on or off and the current
+ * brightness controls leaving the {@link DisplayPowerController} to manage the
+ * details of how the transitions between states should occur.  The goal is for
+ * the {@link PowerManagerService} to focus on the global power state and not
+ * have to micro-manage screen off animations, auto-brightness and other effects.
+ */
+final class DisplayPowerRequest {
+    public static final int SCREEN_STATE_OFF = 0;
+    public static final int SCREEN_STATE_DIM = 1;
+    public static final int SCREEN_STATE_BRIGHT = 2;
+
+    // The requested minimum screen power state: off, dim or bright.
+    public int screenState;
+
+    // If true, the proximity sensor overrides the screen state when an object is
+    // nearby, turning it off temporarily until the object is moved away.
+    public boolean useProximitySensor;
+
+    // The desired screen brightness in the range 0 (minimum / off) to 255 (brightest).
+    // The display power controller may choose to clamp the brightness.
+    // When auto-brightness is enabled, this field should specify a nominal default
+    // value to use while waiting for the light sensor to report enough data.
+    public int screenBrightness;
+
+    // If true, enables automatic brightness control.
+    public boolean useAutoBrightness;
+
+    public DisplayPowerRequest() {
+        screenState = SCREEN_STATE_BRIGHT;
+        useProximitySensor = false;
+        screenBrightness = PowerManager.BRIGHTNESS_ON;
+        useAutoBrightness = false;
+    }
+
+    public DisplayPowerRequest(DisplayPowerRequest other) {
+        copyFrom(other);
+    }
+
+    public void copyFrom(DisplayPowerRequest other) {
+        screenState = other.screenState;
+        useProximitySensor = other.useProximitySensor;
+        screenBrightness = other.screenBrightness;
+        useAutoBrightness = other.useAutoBrightness;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof DisplayPowerRequest
+                && equals((DisplayPowerRequest)o);
+    }
+
+    public boolean equals(DisplayPowerRequest other) {
+        return other != null
+                && screenState == other.screenState
+                && useProximitySensor == other.useProximitySensor
+                && screenBrightness == other.screenBrightness
+                && useAutoBrightness == other.useAutoBrightness;
+    }
+
+    @Override
+    public int hashCode() {
+        return 0; // don't care
+    }
+
+    @Override
+    public String toString() {
+        return "screenState=" + screenState
+                + ", useProximitySensor=" + useProximitySensor
+                + ", screenBrightness=" + screenBrightness
+                + ", useAutoBrightness=" + useAutoBrightness;
+    }
+}
diff --git a/services/java/com/android/server/power/DisplayPowerState.java b/services/java/com/android/server/power/DisplayPowerState.java
new file mode 100644
index 0000000..ad242c0
--- /dev/null
+++ b/services/java/com/android/server/power/DisplayPowerState.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.os.Looper;
+import android.os.PowerManager;
+import android.util.FloatProperty;
+import android.util.IntProperty;
+import android.util.Slog;
+import android.view.Choreographer;
+
+import java.io.PrintWriter;
+
+/**
+ * Represents the current display power state and realizes it.
+ *
+ * This component is similar in nature to a {@link View} except that it describes
+ * the properties of a display.  When properties are changed, the component
+ * invalidates itself and posts a callback to the {@link Choreographer} to
+ * apply the changes.  This mechanism enables the display power state to be
+ * animated smoothly by the animation framework.
+ *
+ * This component must only be created or accessed by the {@link Looper} thread
+ * that belongs to the {@link DisplayPowerController}.
+ *
+ * We don't need to worry about holding a suspend blocker here because the
+ * {@link DisplayPowerController} does that for us whenever there is a pending invalidate.
+ */
+final class DisplayPowerState {
+    private static final String TAG = "DisplayPowerState";
+
+    private static boolean DEBUG = false;
+
+    private static final int DIRTY_SCREEN_ON = 1 << 0;
+    private static final int DIRTY_ELECTRON_BEAM = 1 << 1;
+    private static final int DIRTY_BRIGHTNESS = 1 << 2;
+
+    private static final int DIRTY_ALL = 0xffffffff;
+
+    private final Choreographer mChoreographer;
+    private final ElectronBeam mElectronBeam;
+    private final PhotonicModulator mScreenBrightnessModulator;
+
+    private int mDirty;
+    private boolean mScreenOn;
+    private float mElectronBeamLevel;
+    private int mScreenBrightness;
+
+    private Runnable mCleanListener;
+
+    public DisplayPowerState(ElectronBeam electronBean,
+            PhotonicModulator screenBrightnessModulator) {
+        mChoreographer = Choreographer.getInstance();
+        mElectronBeam = electronBean;
+        mScreenBrightnessModulator = screenBrightnessModulator;
+
+        mScreenOn = true;
+        mElectronBeamLevel = 1.0f;
+        mScreenBrightness = PowerManager.BRIGHTNESS_ON;
+        invalidate(DIRTY_ALL);
+    }
+
+    public static final FloatProperty<DisplayPowerState> ELECTRON_BEAM_LEVEL =
+            new FloatProperty<DisplayPowerState>("electronBeamLevel") {
+        @Override
+        public void setValue(DisplayPowerState object, float value) {
+            object.setElectronBeamLevel(value);
+        }
+
+        @Override
+        public Float get(DisplayPowerState object) {
+            return object.getElectronBeamLevel();
+        }
+    };
+
+    public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
+            new IntProperty<DisplayPowerState>("screenBrightness") {
+        @Override
+        public void setValue(DisplayPowerState object, int value) {
+            object.setScreenBrightness(value);
+        }
+
+        @Override
+        public Integer get(DisplayPowerState object) {
+            return object.getScreenBrightness();
+        }
+    };
+
+    /**
+     * Sets whether the screen is on or off.
+     */
+    public void setScreenOn(boolean on) {
+        if (mScreenOn != on) {
+            if (DEBUG) {
+                Slog.d(TAG, "setScreenOn: on=" + on);
+            }
+
+            mScreenOn = on;
+            invalidate(DIRTY_SCREEN_ON);
+        }
+    }
+
+    /**
+     * Returns true if the screen is on.
+     */
+    public boolean isScreenOn() {
+        return mScreenOn;
+    }
+
+    /**
+     * Prepares the electron beam to turn on or off.
+     * This method should be called before starting an animation because it
+     * can take a fair amount of time to prepare the electron beam surface.
+     *
+     * @param warmUp True if the electron beam should start warming up.
+     * @return True if the electron beam was prepared.
+     */
+    public boolean prepareElectronBeam(boolean warmUp) {
+        boolean success = mElectronBeam.prepare(warmUp);
+        invalidate(DIRTY_ELECTRON_BEAM);
+        return success;
+    }
+
+    /**
+     * Dismisses the electron beam surface.
+     */
+    public void dismissElectronBeam() {
+        mElectronBeam.dismiss();
+    }
+
+    /**
+     * Sets the level of the electron beam steering current.
+     *
+     * The display is blanked when the level is 0.0.  In normal use, the electron
+     * beam should have a value of 1.0.  The electron beam is unstable in between
+     * these states and the picture quality may be compromised.  For best effect,
+     * the electron beam should be warmed up or cooled off slowly.
+     *
+     * Warning: Electron beam emits harmful radiation.  Avoid direct exposure to
+     * skin or eyes.
+     *
+     * @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
+     */
+    public void setElectronBeamLevel(float level) {
+        if (mElectronBeamLevel != level) {
+            if (DEBUG) {
+                Slog.d(TAG, "setElectronBeamLevel: level=" + level);
+            }
+
+            mElectronBeamLevel = level;
+            invalidate(DIRTY_ELECTRON_BEAM);
+        }
+    }
+
+    /**
+     * Gets the level of the electron beam steering current.
+     */
+    public float getElectronBeamLevel() {
+        return mElectronBeamLevel;
+    }
+
+    /**
+     * Sets the display brightness.
+     *
+     * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest).
+     */
+    public void setScreenBrightness(int brightness) {
+        if (mScreenBrightness != brightness) {
+            if (DEBUG) {
+                Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
+            }
+
+            mScreenBrightness = brightness;
+            invalidate(DIRTY_BRIGHTNESS);
+        }
+    }
+
+    /**
+     * Gets the screen brightness.
+     */
+    public int getScreenBrightness() {
+        return mScreenBrightness;
+    }
+
+    /**
+     * Returns true if no properties have been invalidated.
+     * Otherwise, returns false and promises to invoke the specified listener
+     * when the properties have all been applied.
+     * The listener always overrides any previously set listener.
+     */
+    public boolean waitUntilClean(Runnable listener) {
+        if (mDirty != 0) {
+            mCleanListener = listener;
+            return false;
+        } else {
+            mCleanListener = null;
+            return true;
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println();
+        pw.println("Display Power State:");
+        pw.println("  mDirty=" + Integer.toHexString(mDirty));
+        pw.println("  mScreenOn=" + mScreenOn);
+        pw.println("  mScreenBrightness=" + mScreenBrightness);
+        pw.println("  mElectronBeamLevel=" + mElectronBeamLevel);
+
+        mElectronBeam.dump(pw);
+    }
+
+    private void invalidate(int dirty) {
+        if (mDirty == 0) {
+            mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
+                    mTraversalRunnable, null);
+        }
+
+        mDirty |= dirty;
+    }
+
+    private void apply() {
+        if (mDirty != 0) {
+            if ((mDirty & DIRTY_SCREEN_ON) != 0 && !mScreenOn) {
+                PowerManagerService.nativeSetScreenState(false);
+            }
+
+            if ((mDirty & DIRTY_ELECTRON_BEAM) != 0) {
+                mElectronBeam.draw(mElectronBeamLevel);
+            }
+
+            if ((mDirty & DIRTY_BRIGHTNESS) != 0) {
+                mScreenBrightnessModulator.setBrightness(mScreenBrightness);
+            }
+
+            if ((mDirty & DIRTY_SCREEN_ON) != 0 && mScreenOn) {
+                PowerManagerService.nativeSetScreenState(true);
+            }
+
+            mDirty = 0;
+
+            if (mCleanListener != null) {
+                mCleanListener.run();
+            }
+        }
+    }
+
+    private final Runnable mTraversalRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mDirty != 0) {
+                apply();
+            }
+        }
+    };
+}
diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java
new file mode 100644
index 0000000..5472148
--- /dev/null
+++ b/services/java/com/android/server/power/ElectronBeam.java
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.opengl.EGL14;
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLSurface;
+import android.opengl.GLES10;
+import android.opengl.GLUtils;
+import android.os.Looper;
+import android.os.Process;
+import android.util.FloatMath;
+import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Surface;
+import android.view.SurfaceSession;
+import android.view.WindowManagerImpl;
+
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+/**
+ * Bzzzoooop!  *crackle*
+ *
+ * Animates a screen transition from on to off or off to on by applying
+ * some GL transformations to a screenshot.
+ *
+ * This component must only be created or accessed by the {@link Looper} thread
+ * that belongs to the {@link DisplayPowerController}.
+ */
+final class ElectronBeam {
+    private static final String TAG = "ElectronBeam";
+
+    private static final boolean DEBUG = false;
+
+    // The layer for the electron beam surface.
+    // This is currently hardcoded to be one layer above the boot animation.
+    private static final int ELECTRON_BEAM_LAYER = 0x40000001;
+
+    // The relative proportion of the animation to spend performing
+    // the horizontal stretch effect.  The remainder is spent performing
+    // the vertical stretch effect.
+    private static final float HSTRETCH_DURATION = 0.3f;
+    private static final float VSTRETCH_DURATION = 1.0f - HSTRETCH_DURATION;
+
+    // Set to true when the animation context has been fully prepared.
+    private boolean mPrepared;
+    private boolean mWarmUp;
+
+    private final DisplayInfo mDisplayInfo = new DisplayInfo();
+    private int mDisplayLayerStack; // layer stack associated with primary display
+    private int mDisplayRotation;
+    private int mDisplayWidth;      // real width, not rotated
+    private int mDisplayHeight;     // real height, not rotated
+    private SurfaceSession mSurfaceSession;
+    private Surface mSurface;
+    private EGLDisplay mEglDisplay;
+    private EGLConfig mEglConfig;
+    private EGLContext mEglContext;
+    private EGLSurface mEglSurface;
+    private boolean mSurfaceVisible;
+
+    // Texture names.  We only use one texture, which contains the screenshot.
+    private final int[] mTexNames = new int[1];
+    private boolean mTexNamesGenerated;
+
+    // Vertex and corresponding texture coordinates.
+    // We have 4 2D vertices, so 8 elements.  The vertices form a quad.
+    private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8);
+    private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8);
+
+    public ElectronBeam() {
+    }
+
+    /**
+     * Warms up the electron beam in preparation for turning on or off.
+     * This method prepares a GL context, and captures a screen shot.
+     *
+     * @param warmUp True if the electron beam is about to be turned on, false if
+     * it is about to be turned off.
+     * @return True if the electron beam is ready, false if it is uncontrollable.
+     */
+    public boolean prepare(boolean warmUp) {
+        if (DEBUG) {
+            Slog.d(TAG, "prepare: warmUp=" + warmUp);
+        }
+
+        mWarmUp = warmUp;
+
+        // Get the display size and adjust it for rotation.
+        Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
+        display.getDisplayInfo(mDisplayInfo);
+        mDisplayLayerStack = display.getDisplayId();
+        mDisplayRotation = mDisplayInfo.rotation;
+        if (mDisplayRotation == Surface.ROTATION_90
+                || mDisplayRotation == Surface.ROTATION_270) {
+            mDisplayWidth = mDisplayInfo.logicalHeight;
+            mDisplayHeight = mDisplayInfo.logicalWidth;
+        } else {
+            mDisplayWidth = mDisplayInfo.logicalWidth;
+            mDisplayHeight = mDisplayInfo.logicalHeight;
+        }
+
+        // Prepare the surface for drawing.
+        if (!createEglContext()
+                || !createEglSurface()
+                || !captureScreenshotTextureAndSetViewport()) {
+            dismiss();
+            return false;
+        }
+
+        mPrepared = true;
+        return true;
+    }
+
+    /**
+     * Dismisses the electron beam animation surface and cleans up.
+     *
+     * To prevent stray photons from leaking out after the electron beam has been
+     * turned off, it is a good idea to defer dismissing the animation until the
+     * electron beam has been turned back on fully.
+     */
+    public void dismiss() {
+        if (DEBUG) {
+            Slog.d(TAG, "dismiss");
+        }
+
+        destroyScreenshotTexture();
+        destroyEglSurface();
+        mPrepared = false;
+    }
+
+    /**
+     * Draws an animation frame showing the electron beam activated at the
+     * specified level.
+     *
+     * @param level The electron beam level.
+     * @return True if successful.
+     */
+    public boolean draw(float level) {
+        if (DEBUG) {
+            Slog.d(TAG, "drawFrame: level=" + level);
+        }
+
+        if (!attachEglContext()) {
+            return false;
+        }
+        try {
+            // Clear frame to solid black.
+            GLES10.glClearColor(0f, 0f, 0f, 1f);
+            GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT);
+
+            // Draw the frame.
+            if (level < HSTRETCH_DURATION) {
+                drawHStretch(1.0f - (level / HSTRETCH_DURATION));
+            } else {
+                drawVStretch(1.0f - ((level - HSTRETCH_DURATION) / VSTRETCH_DURATION));
+            }
+            if (checkGlErrors("drawFrame")) {
+                return false;
+            }
+
+            EGL14.eglSwapBuffers(mEglDisplay, mEglSurface);
+        } finally {
+            detachEglContext();
+        }
+
+        return showEglSurface();
+    }
+
+    /**
+     * Draws a frame where the content of the electron beam is collapsing inwards upon
+     * itself vertically with red / green / blue channels dispersing and eventually
+     * merging down to a single horizontal line.
+     *
+     * @param stretch The stretch factor.  0.0 is no collapse, 1.0 is full collapse.
+     */
+    private void drawVStretch(float stretch) {
+        // compute interpolation scale factors for each color channel
+        final float ar = scurve(stretch, 7.5f);
+        final float ag = scurve(stretch, 8.0f);
+        final float ab = scurve(stretch, 8.5f);
+        if (DEBUG) {
+            Slog.d(TAG, "drawVStretch: stretch=" + stretch
+                    + ", ar=" + ar + ", ag=" + ag + ", ab=" + ab);
+        }
+
+        // set blending
+        GLES10.glBlendFunc(GLES10.GL_ONE, GLES10.GL_ONE);
+        GLES10.glEnable(GLES10.GL_BLEND);
+
+        // bind vertex buffer
+        GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
+        GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
+
+        // bind texture and set blending for drawing planes
+        GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]);
+        GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE,
+                mWarmUp ? GLES10.GL_MODULATE : GLES10.GL_REPLACE);
+        GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
+                GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR);
+        GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
+                GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR);
+        GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
+                GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE);
+        GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
+                GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE);
+        GLES10.glEnable(GLES10.GL_TEXTURE_2D);
+        GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer);
+        GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
+
+        // draw the red plane
+        setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ar);
+        GLES10.glColorMask(true, false, false, true);
+        GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the green plane
+        setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
+        GLES10.glColorMask(false, true, false, true);
+        GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the blue plane
+        setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ab);
+        GLES10.glColorMask(false, false, true, true);
+        GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
+
+        // clean up after drawing planes
+        GLES10.glDisable(GLES10.GL_TEXTURE_2D);
+        GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY);
+        GLES10.glColorMask(true, true, true, true);
+
+        // draw the white highlight (we use the last vertices)
+        if (!mWarmUp) {
+            GLES10.glColor4f(ag, ag, ag, 1.0f);
+            GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
+        }
+
+        // clean up
+        GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
+        GLES10.glDisable(GLES10.GL_BLEND);
+    }
+
+    /**
+     * Draws a frame where the electron beam has been stretched out into
+     * a thin white horizontal line that fades as it expands outwards.
+     *
+     * @param stretch The stretch factor.  0.0 is no stretch / no fade,
+     * 1.0 is maximum stretch / maximum fade.
+     */
+    private void drawHStretch(float stretch) {
+        // compute interpolation scale factor
+        final float ag = scurve(stretch, 8.0f);
+        if (DEBUG) {
+            Slog.d(TAG, "drawHStretch: stretch=" + stretch + ", ag=" + ag);
+        }
+
+        if (stretch < 1.0f) {
+            // bind vertex buffer
+            GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer);
+            GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
+
+            // draw narrow fading white line
+            setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
+            GLES10.glColor4f(1.0f - ag, 1.0f - ag, 1.0f - ag, 1.0f);
+            GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
+
+            // clean up
+            GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
+        }
+    }
+
+    private static void setVStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
+        final float w = dw + (dw * a);
+        final float h = dh - (dh * a);
+        final float x = (dw - w) * 0.5f;
+        final float y = (dh - h) * 0.5f;
+        setQuad(vtx, x, y, w, h);
+    }
+
+    private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
+        final float w = dw + (dw * a);
+        final float h = 1.0f;
+        final float x = (dw - w) * 0.5f;
+        final float y = (dh - h) * 0.5f;
+        setQuad(vtx, x, y, w, h);
+    }
+
+    private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) {
+        if (DEBUG) {
+            Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h);
+        }
+        vtx.put(0, x);
+        vtx.put(1, y);
+        vtx.put(2, x);
+        vtx.put(3, y + h);
+        vtx.put(4, x + w);
+        vtx.put(5, y + h);
+        vtx.put(6, x + w);
+        vtx.put(7, y);
+    }
+
+    private boolean captureScreenshotTextureAndSetViewport() {
+        // TODO: Use a SurfaceTexture to avoid the extra texture upload.
+        Bitmap bitmap = Surface.screenshot(mDisplayWidth, mDisplayHeight,
+                0, ELECTRON_BEAM_LAYER - 1);
+        if (bitmap == null) {
+            Slog.e(TAG, "Could not take a screenshot!");
+            return false;
+        }
+        try {
+            if (!attachEglContext()) {
+                return false;
+            }
+            try {
+                if (!mTexNamesGenerated) {
+                    GLES10.glGenTextures(1, mTexNames, 0);
+                    if (checkGlErrors("glGenTextures")) {
+                        return false;
+                    }
+                    mTexNamesGenerated = true;
+                }
+
+                GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]);
+                if (checkGlErrors("glBindTexture")) {
+                    return false;
+                }
+
+                float u = 1.0f;
+                float v = 1.0f;
+                GLUtils.texImage2D(GLES10.GL_TEXTURE_2D, 0, bitmap, 0);
+                if (checkGlErrors("glTexImage2D, first try", false)) {
+                    // Try a power of two size texture instead.
+                    int tw = nextPowerOfTwo(mDisplayWidth);
+                    int th = nextPowerOfTwo(mDisplayHeight);
+                    int format = GLUtils.getInternalFormat(bitmap);
+                    GLES10.glTexImage2D(GLES10.GL_TEXTURE_2D, 0,
+                            format, tw, th, 0,
+                            format, GLES10.GL_UNSIGNED_BYTE, null);
+                    if (checkGlErrors("glTexImage2D, second try")) {
+                        return false;
+                    }
+
+                    GLUtils.texSubImage2D(GLES10.GL_TEXTURE_2D, 0, 0, 0, bitmap);
+                    if (checkGlErrors("glTexSubImage2D")) {
+                        return false;
+                    }
+
+                    u = (float)mDisplayWidth / tw;
+                    v = (float)mDisplayHeight / th;
+                }
+
+                // Set up texture coordinates for a quad.
+                // We might need to change this if the texture ends up being
+                // a different size from the display for some reason.
+                mTexCoordBuffer.put(0, 0f);
+                mTexCoordBuffer.put(1, v);
+                mTexCoordBuffer.put(2, 0f);
+                mTexCoordBuffer.put(3, 0f);
+                mTexCoordBuffer.put(4, u);
+                mTexCoordBuffer.put(5, 0f);
+                mTexCoordBuffer.put(6, u);
+                mTexCoordBuffer.put(7, v);
+
+                // Set up our viewport.
+                GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
+                GLES10.glMatrixMode(GLES10.GL_PROJECTION);
+                GLES10.glLoadIdentity();
+                GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1);
+                GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
+                GLES10.glLoadIdentity();
+                GLES10.glMatrixMode(GLES10.GL_TEXTURE);
+                GLES10.glLoadIdentity();
+            } finally {
+                detachEglContext();
+            }
+        } finally {
+            bitmap.recycle();
+        }
+        return true;
+    }
+
+    private void destroyScreenshotTexture() {
+        if (mTexNamesGenerated) {
+            mTexNamesGenerated = false;
+            if (attachEglContext()) {
+                try {
+                    GLES10.glDeleteTextures(1, mTexNames, 0);
+                    checkGlErrors("glDeleteTextures");
+                } finally {
+                    detachEglContext();
+                }
+            }
+        }
+    }
+
+    private boolean createEglContext() {
+        if (mEglDisplay == null) {
+            mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+            if (mEglDisplay == EGL14.EGL_NO_DISPLAY) {
+                logEglError("eglGetDisplay");
+                return false;
+            }
+
+            int[] version = new int[2];
+            if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) {
+                mEglDisplay = null;
+                logEglError("eglInitialize");
+                return false;
+            }
+        }
+
+        if (mEglConfig == null) {
+            int[] eglConfigAttribList = new int[] {
+                    EGL14.EGL_RED_SIZE, 8,
+                    EGL14.EGL_GREEN_SIZE, 8,
+                    EGL14.EGL_BLUE_SIZE, 8,
+                    EGL14.EGL_ALPHA_SIZE, 8,
+                    EGL14.EGL_NONE
+            };
+            int[] numEglConfigs = new int[1];
+            EGLConfig[] eglConfigs = new EGLConfig[1];
+            if (!EGL14.eglChooseConfig(mEglDisplay, eglConfigAttribList, 0,
+                    eglConfigs, 0, eglConfigs.length, numEglConfigs, 0)) {
+                logEglError("eglChooseConfig");
+                return false;
+            }
+            mEglConfig = eglConfigs[0];
+        }
+
+        if (mEglContext == null) {
+            int[] eglContextAttribList = new int[] {
+                    EGL14.EGL_NONE
+            };
+            mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig,
+                    EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0);
+            if (mEglContext == null) {
+                logEglError("eglCreateContext");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* not used because it is too expensive to create / destroy contexts all of the time
+    private void destroyEglContext() {
+        if (mEglContext != null) {
+            if (!EGL14.eglDestroyContext(mEglDisplay, mEglContext)) {
+                logEglError("eglDestroyContext");
+            }
+            mEglContext = null;
+        }
+    }*/
+
+    private boolean createEglSurface() {
+        if (mSurfaceSession == null) {
+            mSurfaceSession = new SurfaceSession();
+        }
+
+        Surface.openTransaction();
+        try {
+            if (mSurface == null) {
+                try {
+                    mSurface = new Surface(mSurfaceSession, Process.myPid(),
+                            "ElectronBeam", mDisplayLayerStack, mDisplayWidth, mDisplayHeight,
+                            PixelFormat.OPAQUE, Surface.OPAQUE | Surface.HIDDEN);
+                } catch (Surface.OutOfResourcesException ex) {
+                    Slog.e(TAG, "Unable to create surface.", ex);
+                    return false;
+                }
+            }
+
+            mSurface.setSize(mDisplayWidth, mDisplayHeight);
+
+            switch (mDisplayRotation) {
+                case Surface.ROTATION_0:
+                    mSurface.setPosition(0, 0);
+                    mSurface.setMatrix(1, 0, 0, 1);
+                    break;
+                case Surface.ROTATION_90:
+                    mSurface.setPosition(0, mDisplayWidth);
+                    mSurface.setMatrix(0, -1, 1, 0);
+                    break;
+                case Surface.ROTATION_180:
+                    mSurface.setPosition(mDisplayWidth, mDisplayHeight);
+                    mSurface.setMatrix(-1, 0, 0, -1);
+                    break;
+                case Surface.ROTATION_270:
+                    mSurface.setPosition(mDisplayHeight, 0);
+                    mSurface.setMatrix(0, 1, -1, 0);
+                    break;
+            }
+        } finally {
+            Surface.closeTransaction();
+        }
+
+        if (mEglSurface == null) {
+            int[] eglSurfaceAttribList = new int[] {
+                    EGL14.EGL_NONE
+            };
+            mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface,
+                    eglSurfaceAttribList, 0);
+            if (mEglSurface == null) {
+                logEglError("eglCreateWindowSurface");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void destroyEglSurface() {
+        if (mEglSurface != null) {
+            if (!EGL14.eglDestroySurface(mEglDisplay, mEglSurface)) {
+                logEglError("eglDestroySurface");
+            }
+            mEglSurface = null;
+        }
+
+        if (mSurface != null) {
+            Surface.openTransaction();
+            try {
+                mSurface.destroy();
+            } finally {
+                Surface.closeTransaction();
+            }
+            mSurface = null;
+            mSurfaceVisible = false;
+        }
+    }
+
+    private boolean showEglSurface() {
+        if (!mSurfaceVisible) {
+            Surface.openTransaction();
+            try {
+                mSurface.setLayer(ELECTRON_BEAM_LAYER);
+                mSurface.show();
+            } finally {
+                Surface.closeTransaction();
+            }
+            mSurfaceVisible = true;
+        }
+        return true;
+    }
+
+    private boolean attachEglContext() {
+        if (mEglSurface == null) {
+            return false;
+        }
+        if (!EGL14.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+            logEglError("eglMakeCurrent");
+            return false;
+        }
+        return true;
+    }
+
+    private void detachEglContext() {
+        if (mEglDisplay != null) {
+            EGL14.eglMakeCurrent(mEglDisplay,
+                    EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
+        }
+    }
+
+    /**
+     * Interpolates a value in the range 0 .. 1 along a sigmoid curve
+     * yielding a result in the range 0 .. 1 scaled such that:
+     * scurve(0) == 0, scurve(0.5) == 0.5, scurve(1) == 1.
+     */
+    private static float scurve(float value, float s) {
+        // A basic sigmoid has the form y = 1.0f / FloatMap.exp(-x * s).
+        // Here we take the input datum and shift it by 0.5 so that the
+        // domain spans the range -0.5 .. 0.5 instead of 0 .. 1.
+        final float x = value - 0.5f;
+
+        // Next apply the sigmoid function to the scaled value
+        // which produces a value in the range 0 .. 1 so we subtract
+        // 0.5 to get a value in the range -0.5 .. 0.5 instead.
+        final float y = sigmoid(x, s) - 0.5f;
+
+        // To obtain the desired boundary conditions we need to scale
+        // the result so that it fills a range of -1 .. 1.
+        final float v = sigmoid(0.5f, s) - 0.5f;
+
+        // And finally remap the value back to a range of 0 .. 1.
+        return y / v * 0.5f + 0.5f;
+    }
+
+    private static float sigmoid(float x, float s) {
+        return 1.0f / (1.0f + FloatMath.exp(-x * s));
+    }
+
+    private static int nextPowerOfTwo(int value) {
+        return 1 << (32 - Integer.numberOfLeadingZeros(value));
+    }
+
+    private static FloatBuffer createNativeFloatBuffer(int size) {
+        ByteBuffer bb = ByteBuffer.allocateDirect(size * 4);
+        bb.order(ByteOrder.nativeOrder());
+        return bb.asFloatBuffer();
+    }
+
+    private static void logEglError(String func) {
+        Slog.e(TAG, func + " failed: error " + EGL14.eglGetError(), new Throwable());
+    }
+
+    private static boolean checkGlErrors(String func) {
+        return checkGlErrors(func, true);
+    }
+
+    private static boolean checkGlErrors(String func, boolean log) {
+        boolean hadError = false;
+        int error;
+        while ((error = GLES10.glGetError()) != GLES10.GL_NO_ERROR) {
+            if (log) {
+                Slog.e(TAG, func + " failed: error " + error, new Throwable());
+            }
+            hadError = true;
+        }
+        return hadError;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println();
+        pw.println("Electron Beam State:");
+        pw.println("  mPrepared=" + mPrepared);
+        pw.println("  mWarmUp=" + mWarmUp);
+        pw.println("  mDisplayLayerStack=" + mDisplayLayerStack);
+        pw.println("  mDisplayRotation=" + mDisplayRotation);
+        pw.println("  mDisplayWidth=" + mDisplayWidth);
+        pw.println("  mDisplayHeight=" + mDisplayHeight);
+        pw.println("  mSurfaceVisible=" + mSurfaceVisible);
+    }
+}
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
new file mode 100644
index 0000000..37384d2
--- /dev/null
+++ b/services/java/com/android/server/power/Notifier.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.server.EventLogTags;
+
+import android.app.ActivityManagerNative;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.BatteryStats;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.WorkSource;
+import android.util.EventLog;
+import android.util.Slog;
+import android.view.WindowManagerPolicy;
+import android.view.WindowManagerPolicy.ScreenOnListener;
+
+/**
+ * Sends broadcasts about important power state changes.
+ *
+ * This methods of this class may be called by the power manager service while
+ * its lock is being held.  Internally it takes care of sending broadcasts to
+ * notify other components of the system or applications asynchronously.
+ *
+ * The notifier is designed to collapse unnecessary broadcasts when it is not
+ * possible for the system to have observed an intermediate state.
+ *
+ * For example, if the device wakes up, goes to sleep and wakes up again immediately
+ * before the go to sleep broadcast has been sent, then no broadcast will be
+ * sent about the system going to sleep and waking up.
+ */
+final class Notifier {
+    private static final String TAG = "PowerManagerNotifier";
+
+    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 MSG_USER_ACTIVITY = 1;
+    private static final int MSG_BROADCAST = 2;
+
+    private final Object mLock = new Object();
+
+    private final Context mContext;
+    private final IBatteryStats mBatteryStats;
+    private final SuspendBlocker mSuspendBlocker;
+    private final WindowManagerPolicy mPolicy;
+    private final ScreenOnListener mScreenOnListener;
+
+    private final NotifierHandler mHandler;
+    private final Intent mScreenOnIntent;
+    private final Intent mScreenOffIntent;
+
+    // The current power state.
+    private int mActualPowerState;
+    private int mLastGoToSleepReason;
+
+    // The currently broadcasted power state.  This reflects what other parts of the
+    // system have observed.
+    private int mBroadcastedPowerState;
+    private boolean mBroadcastInProgress;
+    private long mBroadcastStartTime;
+
+    // True if a user activity message should be sent.
+    private boolean mUserActivityPending;
+
+    public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
+            SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
+            ScreenOnListener screenOnListener) {
+        mContext = context;
+        mBatteryStats = batteryStats;
+        mSuspendBlocker = suspendBlocker;
+        mPolicy = policy;
+        mScreenOnListener = screenOnListener;
+
+        mHandler = new NotifierHandler(looper);
+        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
+        mScreenOnIntent.addFlags(
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+        mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
+        mScreenOffIntent.addFlags(
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+    }
+
+    /**
+     * Called when a wake lock is acquired.
+     */
+    public void onWakeLockAcquired(int flags, String tag, int ownerUid, int ownerPid,
+            WorkSource workSource) {
+        if (DEBUG) {
+            Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
+                    + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+                    + ", workSource=" + workSource);
+        }
+
+        if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
+            try {
+                final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+                if (workSource != null) {
+                    mBatteryStats.noteStartWakelockFromSource(
+                            workSource, ownerPid, tag, monitorType);
+                } else {
+                    mBatteryStats.noteStartWakelock(
+                            ownerUid, ownerPid, tag, monitorType);
+                }
+            } catch (RemoteException ex) {
+                // Ignore
+            }
+        }
+    }
+
+    /**
+     * Called when a wake lock is released.
+     */
+    public void onWakeLockReleased(int flags, String tag, int ownerUid, int ownerPid,
+            WorkSource workSource) {
+        if (DEBUG) {
+            Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
+                    + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+                    + ", workSource=" + workSource);
+        }
+
+        if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
+            try {
+                final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+                if (workSource != null) {
+                    mBatteryStats.noteStopWakelockFromSource(
+                            workSource, ownerPid, tag, monitorType);
+                } else {
+                    mBatteryStats.noteStopWakelock(
+                            ownerUid, ownerPid, tag, monitorType);
+                }
+            } catch (RemoteException ex) {
+                // Ignore
+            }
+        }
+    }
+
+    private static boolean isWakeLockAlreadyReportedToBatteryStats(String tag, int uid) {
+        // The window manager already takes care of reporting battery stats associated
+        // with the use of the KEEP_SCREEN_ON_FLAG.
+        // TODO: Use a WorkSource to handle this situation instead of hardcoding it here.
+        return uid == Process.SYSTEM_UID
+                && tag.equals(PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
+    }
+
+    private static int getBatteryStatsWakeLockMonitorType(int flags) {
+        switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+            case PowerManager.PARTIAL_WAKE_LOCK:
+            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+                return BatteryStats.WAKE_TYPE_PARTIAL;
+            default:
+                return BatteryStats.WAKE_TYPE_FULL;
+        }
+    }
+
+    /**
+     * Called when the screen is turned on.
+     */
+    public void onScreenOn() {
+        if (DEBUG) {
+            Slog.d(TAG, "onScreenOn");
+        }
+
+        try {
+            mBatteryStats.noteScreenOn();
+        } catch (RemoteException ex) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Called when the screen is turned off.
+     */
+    public void onScreenOff() {
+        if (DEBUG) {
+            Slog.d(TAG, "onScreenOff");
+        }
+
+        try {
+            mBatteryStats.noteScreenOff();
+        } catch (RemoteException ex) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Called when the screen changes brightness.
+     */
+    public void onScreenBrightness(int brightness) {
+        if (DEBUG) {
+            Slog.d(TAG, "onScreenBrightness: brightness=" + brightness);
+        }
+
+        try {
+            mBatteryStats.noteScreenBrightness(brightness);
+        } catch (RemoteException ex) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Called when the device is waking up from sleep and the
+     * display is about to be turned on.
+     */
+    public void onWakeUpStarted() {
+        if (DEBUG) {
+            Slog.d(TAG, "onWakeUpStarted");
+        }
+
+        synchronized (mLock) {
+            if (mActualPowerState != POWER_STATE_AWAKE) {
+                mActualPowerState = POWER_STATE_AWAKE;
+                updatePendingBroadcastLocked();
+            }
+        }
+    }
+
+    /**
+     * Called when the device has finished waking up from sleep
+     * and the display has been turned on.
+     */
+    public void onWakeUpFinished() {
+        if (DEBUG) {
+            Slog.d(TAG, "onWakeUpFinished");
+        }
+    }
+
+    /**
+     * Called when the device is going to sleep.
+     */
+    public void onGoToSleepStarted(int reason) {
+        if (DEBUG) {
+            Slog.d(TAG, "onGoToSleepStarted");
+        }
+
+        synchronized (mLock) {
+            mLastGoToSleepReason = reason;
+        }
+    }
+
+    /**
+     * Called when the device has finished going to sleep and the
+     * display has been turned off.
+     *
+     * 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.
+     */
+    public void onGoToSleepFinished() {
+        if (DEBUG) {
+            Slog.d(TAG, "onGoToSleepFinished");
+        }
+
+        synchronized (mLock) {
+            if (mActualPowerState != POWER_STATE_ASLEEP) {
+                mActualPowerState = POWER_STATE_ASLEEP;
+                if (mUserActivityPending) {
+                    mUserActivityPending = false;
+                    mHandler.removeMessages(MSG_USER_ACTIVITY);
+                }
+                updatePendingBroadcastLocked();
+            }
+        }
+    }
+
+    /**
+     * Called when there has been user activity.
+     */
+    public void onUserActivity(int event, int uid) {
+        if (DEBUG) {
+            Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
+        }
+
+        try {
+            mBatteryStats.noteUserActivity(uid, event);
+        } catch (RemoteException ex) {
+            // Ignore
+        }
+
+        synchronized (mLock) {
+            if (!mUserActivityPending) {
+                mUserActivityPending = true;
+                Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
+                msg.setAsynchronous(true);
+                mHandler.sendMessage(msg);
+            }
+        }
+    }
+
+    private void updatePendingBroadcastLocked() {
+        if (!mBroadcastInProgress
+                && mActualPowerState != POWER_STATE_UNKNOWN
+                && mActualPowerState != mBroadcastedPowerState) {
+            mBroadcastInProgress = true;
+            mSuspendBlocker.acquire();
+            Message msg = mHandler.obtainMessage(MSG_BROADCAST);
+            msg.setAsynchronous(true);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    private void sendUserActivity() {
+        synchronized (mLock) {
+            if (!mUserActivityPending) {
+                return;
+            }
+            mUserActivityPending = false;
+        }
+
+        mPolicy.userActivity();
+    }
+
+    private void sendNextBroadcast() {
+        final int powerState;
+        final int goToSleepReason;
+        synchronized (mLock) {
+            if (mActualPowerState == POWER_STATE_UNKNOWN
+                    || mActualPowerState == mBroadcastedPowerState) {
+                mBroadcastInProgress = false;
+                mSuspendBlocker.release();
+                return;
+            }
+
+            powerState = mActualPowerState;
+            goToSleepReason = mLastGoToSleepReason;
+
+            mBroadcastedPowerState = powerState;
+            mBroadcastStartTime = SystemClock.uptimeMillis();
+        }
+
+        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
+
+        if (powerState == POWER_STATE_AWAKE) {
+            sendWakeUpBroadcast();
+        } else {
+            sendGoToSleepBroadcast(goToSleepReason);
+        }
+    }
+
+    private void sendWakeUpBroadcast() {
+        if (DEBUG) {
+            Slog.d(TAG, "Sending wake up broadcast.");
+        }
+
+        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
+
+        mPolicy.screenTurningOn(mScreenOnListener);
+        try {
+            ActivityManagerNative.getDefault().wakingUp();
+        } catch (RemoteException e) {
+            // ignore it
+        }
+
+        if (ActivityManagerNative.isSystemReady()) {
+            mContext.sendOrderedBroadcast(mScreenOnIntent, null,
+                    mWakeUpBroadcastDone, mHandler, 0, null, null);
+        } else {
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
+            sendNextBroadcast();
+        }
+    }
+
+    private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
+                    SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
+            sendNextBroadcast();
+        }
+    };
+
+    private void sendGoToSleepBroadcast(int reason) {
+        if (DEBUG) {
+            Slog.d(TAG, "Sending go to sleep broadcast.");
+        }
+
+        int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
+        switch (reason) {
+            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
+                why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
+                break;
+            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
+                why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
+                break;
+        }
+
+        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
+
+        mPolicy.screenTurnedOff(why);
+        try {
+            ActivityManagerNative.getDefault().goingToSleep();
+        } catch (RemoteException e) {
+            // ignore it.
+        }
+
+        if (ActivityManagerNative.isSystemReady()) {
+            mContext.sendOrderedBroadcast(mScreenOffIntent, null,
+                    mGoToSleepBroadcastDone, mHandler, 0, null, null);
+        } else {
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
+            sendNextBroadcast();
+        }
+    }
+
+    private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
+                    SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
+            sendNextBroadcast();
+        }
+    };
+
+    private final class NotifierHandler extends Handler {
+        public NotifierHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_USER_ACTIVITY:
+                    sendUserActivity();
+                    break;
+
+                case MSG_BROADCAST:
+                    sendNextBroadcast();
+                    break;
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/power/PhotonicModulator.java b/services/java/com/android/server/power/PhotonicModulator.java
new file mode 100644
index 0000000..f7c9c7d
--- /dev/null
+++ b/services/java/com/android/server/power/PhotonicModulator.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import com.android.server.LightsService;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Sets the value of a light asynchronously.
+ *
+ * This is done to avoid blocking the looper on devices for which
+ * setting the backlight brightness is especially slow.
+ */
+final class PhotonicModulator {
+    private static final int UNKNOWN_LIGHT_VALUE = -1;
+
+    private final Object mLock = new Object();
+
+    private final LightsService.Light mLight;
+    private final Executor mExecutor;
+    private final SuspendBlocker mSuspendBlocker;
+
+    private boolean mPendingChange;
+    private int mPendingLightValue;
+    private int mActualLightValue;
+
+    public PhotonicModulator(Executor executor, LightsService.Light light,
+            SuspendBlocker suspendBlocker) {
+        mExecutor = executor;
+        mLight = light;
+        mSuspendBlocker = suspendBlocker;
+        mPendingLightValue = UNKNOWN_LIGHT_VALUE;
+        mActualLightValue = UNKNOWN_LIGHT_VALUE;
+    }
+
+    /**
+     * Asynchronously sets the backlight brightness.
+     *
+     * @param lightValue The new light value, from 0 to 255.
+     */
+    public void setBrightness(int lightValue) {
+        synchronized (mLock) {
+            if (lightValue != mPendingLightValue) {
+                mPendingLightValue = lightValue;
+                if (!mPendingChange) {
+                    mPendingChange = true;
+                    mSuspendBlocker.acquire();
+                    mExecutor.execute(mTask);
+                }
+            }
+        }
+    }
+
+    private final Runnable mTask = new Runnable() {
+        @Override
+        public void run() {
+            for (;;) {
+                final int newLightValue;
+                synchronized (mLock) {
+                    newLightValue = mPendingLightValue;
+                    if (newLightValue == mActualLightValue) {
+                        mSuspendBlocker.release();
+                        mPendingChange = false;
+                        return;
+                    }
+                    mActualLightValue = newLightValue;
+                }
+                mLight.setBrightness(newLightValue);
+            }
+        }
+    };
+}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 2630239..2d91e6c 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -21,2767 +21,1432 @@
 import com.android.server.EventLogTags;
 import com.android.server.LightsService;
 import com.android.server.Watchdog;
-import com.android.server.am.BatteryStatsService;
+import com.android.server.am.ActivityManagerService;
 import com.android.server.display.DisplayManagerService;
 
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
+import android.Manifest;
 import android.content.BroadcastReceiver;
-import android.content.ContentQueryMap;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.database.Cursor;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.hardware.SystemSensorManager;
+import android.net.Uri;
 import android.os.BatteryManager;
-import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.IPowerManager;
-import android.os.LocalPowerManager;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.service.dreams.IDreamManager;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.TimeUtils;
 import android.view.WindowManagerPolicy;
-import static android.view.WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR;
-import static android.provider.Settings.System.DIM_SCREEN;
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS;
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
-import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-import static android.provider.Settings.System.STAY_ON_WHILE_PLUGGED_IN;
-import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
-import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Observable;
-import java.util.Observer;
 
-public class PowerManagerService extends IPowerManager.Stub
-        implements LocalPowerManager, Watchdog.Monitor {
-    private static final int NOMINAL_FRAME_TIME_MS = 1000/60;
+import libcore.util.Objects;
 
+/**
+ * The power manager service is responsible for coordinating power management
+ * functions on the device.
+ */
+public final class PowerManagerService extends IPowerManager.Stub
+        implements Watchdog.Monitor {
     private static final String TAG = "PowerManagerService";
-    static final String PARTIAL_NAME = "PowerManagerService";
 
-    // could be either static or controllable at runtime
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_PROXIMITY_SENSOR = (false || DEBUG);
-    private static final boolean DEBUG_LIGHT_SENSOR = (false || DEBUG);
-    private static final boolean DEBUG_LIGHT_ANIMATION = (false || DEBUG);
-    private static final boolean DEBUG_SCREEN_ON = false;
+    private static final boolean DEBUG_SPEW = DEBUG && true;
 
-    // Wake lock that ensures that the CPU is running.  The screen might not be on.
-    private static final int PARTIAL_WAKE_LOCK_ID = 1;
+    // Message: Sent when a user activity timeout occurs to update the power state.
+    private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
+    // Message: Sent when the device enters or exits a napping or dreaming state.
+    private static final int MSG_SANDMAN = 2;
 
-    // Wake lock that ensures that the screen is on.
-    private static final int FULL_WAKE_LOCK_ID = 2;
+    // Dirty bit: mWakeLocks changed
+    private static final int DIRTY_WAKE_LOCKS = 1 << 0;
+    // Dirty bit: mWakefulness changed
+    private static final int DIRTY_WAKEFULNESS = 1 << 1;
+    // Dirty bit: user activity was poked or may have timed out
+    private static final int DIRTY_USER_ACTIVITY = 1 << 2;
+    // Dirty bit: actual display power state was updated asynchronously
+    private static final int DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED = 1 << 3;
+    // Dirty bit: mBootCompleted changed
+    private static final int DIRTY_BOOT_COMPLETED = 1 << 4;
+    // Dirty bit: settings changed
+    private static final int DIRTY_SETTINGS = 1 << 5;
+    // Dirty bit: mIsPowered changed
+    private static final int DIRTY_IS_POWERED = 1 << 6;
+    // Dirty bit: mStayOn changed
+    private static final int DIRTY_STAY_ON = 1 << 7;
+    // Dirty bit: battery state changed
+    private static final int DIRTY_BATTERY_STATE = 1 << 8;
 
-    private static final boolean LOG_PARTIAL_WL = false;
+    // 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.
+    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 napping.
+    private static final int WAKEFULNESS_AWAKE = 1;
+    // Wakefulness: The device is napping.  It is deciding whether to dream or go to sleep
+    // but hasn't gotten around to it yet.  It can be awoken by a call to wakeUp(), which
+    // ends the nap. User activity may brighten the screen but does not end the nap.
+    private static final int WAKEFULNESS_NAPPING = 2;
+    // 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 = 3;
 
-    private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
-                                        | PowerManager.SCREEN_DIM_WAKE_LOCK
-                                        | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
-                                        | PowerManager.FULL_WAKE_LOCK
-                                        | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
+    // 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;
+    private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
+    private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
+    private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
 
-    //                       time since last state:               time since last event:
-    // The short keylight delay comes from secure settings; this is the default.
-    private static final int SHORT_KEYLIGHT_DELAY_DEFAULT = 6000; // t+6 sec
-    private static final int MEDIUM_KEYLIGHT_DELAY = 15000;       // t+15 sec
-    private static final int LONG_KEYLIGHT_DELAY = 6000;        // t+6 sec
-    private static final int LONG_DIM_TIME = 7000;              // t+N-5 sec
+    // Summarizes the user activity state.
+    private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
+    private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
 
-    // How long to wait to debounce light sensor changes in milliseconds
-    private static final int LIGHT_SENSOR_DELAY = 2000;
+    // Default and minimum screen off timeout in milliseconds.
+    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
+    private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
 
-    // light sensor events rate in microseconds
-    private static final int LIGHT_SENSOR_RATE = 1000000;
+    // The screen dim duration, in seconds.
+    // This is subtracted from the end of the screen off timeout so the
+    // minimum screen off timeout should be longer than this.
+    private static final int SCREEN_DIM_DURATION = 7 * 1000;
 
-    // Expansion of range of light values when applying scale from light
-    // sensor brightness setting, in the [0..255] brightness range.
-    private static final int LIGHT_SENSOR_RANGE_EXPANSION = 20;
-
-    // Scaling factor of the light sensor brightness setting when applying
-    // it to the final brightness.
-    private static final int LIGHT_SENSOR_OFFSET_SCALE = 8;
-
-    // For debouncing the proximity sensor in milliseconds
-    private static final int PROXIMITY_SENSOR_DELAY = 1000;
-
-    // trigger proximity if distance is less than 5 cm
-    private static final float PROXIMITY_THRESHOLD = 5.0f;
-
-    // Cached secure settings; see updateSettingsValues()
-    private int mShortKeylightDelay = SHORT_KEYLIGHT_DELAY_DEFAULT;
-
-    // Default timeout for screen off, if not found in settings database = 15 seconds.
-    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15000;
-
-    // Screen brightness should always have a value, but just in case...
-    private static final int DEFAULT_SCREEN_BRIGHTNESS = 192;
-
-    // Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
-    // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
-    private static final int LOW_BATTERY_THRESHOLD = 10;
-
-    // flags for setPowerState
-    private static final int ALL_LIGHTS_OFF         = 0x00000000;
-    private static final int SCREEN_ON_BIT          = 0x00000001;
-    private static final int SCREEN_BRIGHT_BIT      = 0x00000002;
-    private static final int BUTTON_BRIGHT_BIT      = 0x00000004;
-    private static final int KEYBOARD_BRIGHT_BIT    = 0x00000008;
-    private static final int BATTERY_LOW_BIT        = 0x00000010;
-
-    // values for setPowerState
-
-    // SCREEN_OFF == everything off
-    private static final int SCREEN_OFF         = 0x00000000;
-
-    // SCREEN_DIM == screen on, screen backlight dim
-    private static final int SCREEN_DIM         = SCREEN_ON_BIT;
-
-    // SCREEN_BRIGHT == screen on, screen backlight bright
-    private static final int SCREEN_BRIGHT      = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;
-
-    // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright
-    private static final int SCREEN_BUTTON_BRIGHT  = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;
-
-    // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright
-    private static final int ALL_BRIGHT         = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;
-
-    // used for noChangeLights in setPowerState()
-    private static final int LIGHTS_MASK        = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
-
-    // animate screen lights in PowerManager (as opposed to SurfaceFlinger)
-    boolean mAnimateScreenLights = true;
-
-    static final int ANIM_STEPS = 60; // nominal # of frames at 60Hz
-    // Slower animation for autobrightness changes
-    static final int AUTOBRIGHTNESS_ANIM_STEPS = 2 * ANIM_STEPS;
-    // Even slower animation for autodimness changes. Set to max to effectively disable dimming.
-    // Note 100 is used to keep the mWindowScaleAnimation scaling below from overflowing an int.
-    static final int AUTODIMNESS_ANIM_STEPS = Integer.MAX_VALUE / (NOMINAL_FRAME_TIME_MS * 100);
-    // Number of steps when performing a more immediate brightness change.
-    static final int IMMEDIATE_ANIM_STEPS = 4;
-
-    // These magic numbers are the initial state of the LEDs at boot.  Ideally
-    // we should read them from the driver, but our current hardware returns 0
-    // for the initial value.  Oops!
-    static final int INITIAL_SCREEN_BRIGHTNESS = 255;
-    static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
-    static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF;
-
-    private final int MY_UID;
-    private final int MY_PID;
-
-    private boolean mDoneBooting = false;
-    private boolean mBootCompleted = false;
-    private boolean mHeadless = false;
-    private int mStayOnConditions = 0;
-    private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
-    private final int[] mBroadcastWhy = new int[3];
-    private boolean mPreparingForScreenOn = false;
-    private boolean mSkippedScreenOn = false;
-    private boolean mInitialized = false;
-    private int mPartialCount = 0;
-    private int mPowerState;
-    // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
-    // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
-    private int mScreenOffReason;
-    private int mUserState;
-    private boolean mKeyboardVisible = false;
-    private boolean mUserActivityAllowed = true;
-    private int mProximityWakeLockCount = 0;
-    private boolean mProximitySensorEnabled = false;
-    private boolean mProximitySensorActive = false;
-    private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active
-    private long mLastProximityEventTime;
-    private int mScreenOffTimeoutSetting;
-    private int mMaximumScreenOffTimeout = Integer.MAX_VALUE;
-    private int mKeylightDelay;
-    private int mDimDelay;
-    private int mScreenOffDelay;
-    private int mWakeLockState;
-    private long mLastEventTime = 0;
-    private long mScreenOffTime;
-    private volatile WindowManagerPolicy mPolicy;
-    private final LockList mLocks = new LockList();
-    private Intent mScreenOffIntent;
-    private Intent mScreenOnIntent;
-    private LightsService mLightsService;
     private Context mContext;
-    private LightsService.Light mLcdLight;
-    private LightsService.Light mButtonLight;
-    private LightsService.Light mKeyboardLight;
-    private LightsService.Light mAttentionLight;
-    private UnsynchronizedWakeLock mBroadcastWakeLock;
-    private UnsynchronizedWakeLock mStayOnWhilePluggedInScreenDimLock;
-    private UnsynchronizedWakeLock mStayOnWhilePluggedInPartialLock;
-    private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
-    private UnsynchronizedWakeLock mProximityPartialLock;
-    private HandlerThread mHandlerThread;
-    private Handler mScreenOffHandler;
-    private Handler mScreenBrightnessHandler;
-    private Handler mHandler;
-    private final TimeoutTask mTimeoutTask = new TimeoutTask();
-    private ScreenBrightnessAnimator mScreenBrightnessAnimator;
-    private boolean mWaitingForFirstLightSensor = false;
-    private boolean mStillNeedSleepNotification;
-    private boolean mIsPowered = false;
-    private IActivityManager mActivityService;
-    private IBatteryStats mBatteryStats;
+    private LightsService mLightsService;
     private BatteryService mBatteryService;
-    private DisplayManagerService mDisplayManagerService;
-    private SensorManager mSensorManager;
-    private Sensor mProximitySensor;
-    private Sensor mLightSensor;
-    private boolean mLightSensorEnabled;
-    private float mLightSensorValue = -1;
-    private boolean mProxIgnoredBecauseScreenTurnedOff = false;
-    private int mHighestLightSensorValue = -1;
-    private boolean mLightSensorPendingDecrease = false;
-    private boolean mLightSensorPendingIncrease = false;
-    private float mLightSensorPendingValue = -1;
-    private float mLightSensorAdjustSetting = 0;
-    private int mLightSensorScreenBrightness = -1;
-    private int mLightSensorButtonBrightness = -1;
-    private int mLightSensorKeyboardBrightness = -1;
-    private boolean mDimScreen = true;
-    private boolean mIsDocked = false;
-    private long mNextTimeout;
-    private volatile int mPokey = 0;
-    private volatile boolean mPokeAwakeOnSet = false;
-    private volatile boolean mInitComplete = false;
-    private final HashMap<IBinder,PokeLock> mPokeLocks = new HashMap<IBinder,PokeLock>();
-    // mLastScreenOnTime is the time the screen was last turned on
-    private long mLastScreenOnTime;
-    private boolean mPreventScreenOn;
-    private int mScreenBrightnessSetting = DEFAULT_SCREEN_BRIGHTNESS;
-    private int mScreenBrightnessOverride = -1;
-    private int mButtonBrightnessOverride = -1;
-    private int mScreenBrightnessDim;
-    private boolean mUseSoftwareAutoBrightness;
-    private boolean mAutoBrightessEnabled;
-    private int[] mAutoBrightnessLevels;
-    private int[] mLcdBacklightValues;
-    private int[] mButtonBacklightValues;
-    private int[] mKeyboardBacklightValues;
-    private int mLightSensorWarmupTime;
-    boolean mUnplugTurnsOnScreen;
-    private int mWarningSpewThrottleCount;
-    private long mWarningSpewThrottleTime;
-    private int mAnimationSetting = ANIM_SETTING_OFF;
-    private float mWindowScaleAnimation;
+    private IBatteryStats mBatteryStats;
+    private HandlerThread mHandlerThread;
+    private PowerManagerHandler mHandler;
+    private WindowManagerPolicy mPolicy;
+    private Notifier mNotifier;
+    private DisplayPowerController mDisplayPowerController;
+    private SettingsObserver mSettingsObserver;
+    private IDreamManager mDreamManager;
+    private LightsService.Light mAttentionLight;
 
-    // Must match with the ISurfaceComposer constants in C++.
-    private static final int ANIM_SETTING_ON = 0x01;
-    private static final int ANIM_SETTING_OFF = 0x10;
+    private final Object mLock = new Object();
+
+    // A bitfield that indicates what parts of the power state have
+    // changed and need to be recalculated.
+    private int mDirty;
+
+    // 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;
+
+    // True if MSG_SANDMAN has been scheduled.
+    private boolean mSandmanScheduled;
+
+    // Table of all suspend blockers.
+    // There should only be a few of these.
+    private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
+
+    // Table of all wake locks acquired by applications.
+    private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
+
+    // A bitfield that summarizes the state of all active wakelocks.
+    private int mWakeLockSummary;
+
+    // If true, instructs the display controller to wait for the proximity sensor to
+    // go negative before turning the screen on.
+    private boolean mRequestWaitForNegativeProximity;
+
+    // Timestamp of the last time the device was awoken or put to sleep.
+    private long mLastWakeTime;
+    private long mLastSleepTime;
+
+    // True if we need to send a wake up or go to sleep finished notification
+    // when the display is ready.
+    private boolean mSendWakeUpFinishedNotificationWhenReady;
+    private boolean mSendGoToSleepFinishedNotificationWhenReady;
+
+    // Timestamp of the last call to user activity.
+    private long mLastUserActivityTime;
+    private long mLastUserActivityTimeNoChangeLights;
+
+    // A bitfield that summarizes the effect of the user activity timer.
+    // A zero value indicates that the user activity timer has expired.
+    private int mUserActivitySummary;
+
+    // The desired display power state.  The actual state may lag behind the
+    // requested because it is updated asynchronously by the display power controller.
+    private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
+
+    // The time the screen was last turned off, in elapsedRealtime() timebase.
+    private long mLastScreenOffEventElapsedRealTime;
+
+    // True if the display power state has been fully applied, which means the display
+    // is actually on or actually off or whatever was requested.
+    private boolean mDisplayReady;
+
+    // True if holding a wake-lock to block suspend of the CPU.
+    private boolean mHoldingWakeLockSuspendBlocker;
+
+    // The suspend blocker used to keep the CPU alive when wake locks have been acquired.
+    private final SuspendBlocker mWakeLockSuspendBlocker;
+
+    // True if systemReady() has been called.
+    private boolean mSystemReady;
+
+    // True if boot completed occurred.  We keep the screen on until this happens.
+    private boolean mBootCompleted;
+
+    // True if the device is plugged into a power source.
+    private boolean mIsPowered;
+
+    // True if the device should wake up when plugged or unplugged.
+    private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
+
+    // True if dreams are supported on this device.
+    private boolean mDreamsSupportedConfig;
+
+    // True if dreams are enabled by the user.
+    private boolean mDreamsEnabledSetting;
+
+    // The screen off timeout setting value in milliseconds.
+    private int mScreenOffTimeoutSetting;
+
+    // The maximum allowable screen off timeout according to the device
+    // administration policy.  Overrides other settings.
+    private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
+
+    // The stay on while plugged in setting.
+    // A bitfield of battery conditions under which to make the screen stay on.
+    private int mStayOnWhilePluggedInSetting;
+
+    // True if the device should stay on.
+    private boolean mStayOn;
+
+    // Screen brightness setting limits.
+    private int mScreenBrightnessSettingMinimum;
+    private int mScreenBrightnessSettingMaximum;
+    private int mScreenBrightnessSettingDefault;
+
+    // The screen brightness setting, from 0 to 255.
+    // Use -1 if no value has been set.
+    private int mScreenBrightnessSetting;
+
+    // The screen brightness mode.
+    // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
+    private int mScreenBrightnessModeSetting;
+
+    // The screen brightness setting override from the window manager
+    // to allow the current foreground activity to override the brightness.
+    // Use -1 to disable.
+    private int mScreenBrightnessOverrideFromWindowManager = -1;
+
+    // The screen brightness setting override from the settings application
+    // to temporarily adjust the brightness until next updated,
+    // Use -1 to disable.
+    private int mTemporaryScreenBrightnessSettingOverride = -1;
 
     private native void nativeInit();
-    private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
-    private native void nativeStartSurfaceFlingerAnimation(int mode);
-    private static native void nativeAcquireWakeLock(int lock, String id);
-    private static native void nativeReleaseWakeLock(String id);
-    private static native int nativeSetScreenState(boolean on);
     private static native void nativeShutdown();
     private static native void nativeReboot(String reason) throws IOException;
 
-    /*
-    static PrintStream mLog;
-    static {
-        try {
-            mLog = new PrintStream("/data/power.log");
-        }
-        catch (FileNotFoundException e) {
-            android.util.Slog.e(TAG, "Life is hard", e);
-        }
-    }
-    static class Log {
-        static void d(String tag, String s) {
-            mLog.println(s);
-            android.util.Slog.d(tag, s);
-        }
-        static void i(String tag, String s) {
-            mLog.println(s);
-            android.util.Slog.i(tag, s);
-        }
-        static void w(String tag, String s) {
-            mLog.println(s);
-            android.util.Slog.w(tag, s);
-        }
-        static void e(String tag, String s) {
-            mLog.println(s);
-            android.util.Slog.e(tag, s);
-        }
-    }
-    */
+    private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
+    private static native void nativeAcquireSuspendBlocker(String name);
+    private static native void nativeReleaseSuspendBlocker(String name);
 
-    /**
-     * This class works around a deadlock between the lock in PowerManager.WakeLock
-     * and our synchronizing on mLocks.  PowerManager.WakeLock synchronizes on its
-     * mToken object so it can be accessed from any thread, but it calls into here
-     * with its lock held.  This class is essentially a reimplementation of
-     * PowerManager.WakeLock, but without that extra synchronized block, because we'll
-     * only call it with our own locks held.
-     */
-    private class UnsynchronizedWakeLock {
-        int mFlags;
-        String mTag;
-        IBinder mToken;
-        int mCount = 0;
-        boolean mRefCounted;
-        boolean mHeld;
-
-        UnsynchronizedWakeLock(int flags, String tag, boolean refCounted) {
-            mFlags = flags;
-            mTag = tag;
-            mToken = new Binder();
-            mRefCounted = refCounted;
-        }
-
-        public void acquire() {
-            if (!mRefCounted || mCount++ == 0) {
-                long ident = Binder.clearCallingIdentity();
-                try {
-                    PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
-                            MY_UID, MY_PID, mTag, null);
-                    mHeld = true;
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
-            }
-        }
-
-        public void release() {
-            if (!mRefCounted || --mCount == 0) {
-                PowerManagerService.this.releaseWakeLockLocked(mToken, 0, false);
-                mHeld = false;
-            }
-            if (mCount < 0) {
-                throw new RuntimeException("WakeLock under-locked " + mTag);
-            }
-        }
-
-        public boolean isHeld()
-        {
-            return mHeld;
-        }
-
-        public String toString() {
-            return "UnsynchronizedWakeLock(mFlags=0x" + Integer.toHexString(mFlags)
-                    + " mCount=" + mCount + " mHeld=" + mHeld + ")";
-        }
-    }
-
-    private final class BatteryReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            synchronized (mLocks) {
-                boolean wasPowered = mIsPowered;
-                mIsPowered = mBatteryService.isPowered();
-
-                if (mIsPowered != wasPowered) {
-                    // update mStayOnWhilePluggedIn wake lock
-                    updateWakeLockLocked();
-
-                    // treat plugging and unplugging the devices as a user activity.
-                    // users find it disconcerting when they unplug the device
-                    // and it shuts off right away.
-                    // to avoid turning on the screen when unplugging, we only trigger
-                    // user activity when screen was already on.
-                    // temporarily set mUserActivityAllowed to true so this will work
-                    // even when the keyguard is on.
-                    // However, you can also set config_unplugTurnsOnScreen to have it
-                    // turn on.  Some devices want this because they don't have a
-                    // charging LED.
-                    synchronized (mLocks) {
-                        if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
-                                mUnplugTurnsOnScreen) {
-                            forceUserActivityLocked();
-                        }
-                    }
-
-                    // stop the screensaver if we're now unplugged
-                    if (mPolicy != null && wasPowered) {
-                        mPolicy.stopScreenSaver();
-                    }
-                }
-            }
-        }
-    }
-
-    private final class BootCompletedReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            bootCompleted();
-        }
-    }
-
-    private final class DockReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                    Intent.EXTRA_DOCK_STATE_UNDOCKED);
-            dockStateChanged(state);
-        }
-    }
-
-    /**
-     * Set the setting that determines whether the device stays on when plugged in.
-     * The argument is a bit string, with each bit specifying a power source that,
-     * when the device is connected to that source, causes the device to stay on.
-     * See {@link android.os.BatteryManager} for the list of power sources that
-     * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
-     * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
-     * @param val an {@code int} containing the bits that specify which power sources
-     * should cause the device to stay on.
-     */
-    public void setStayOnSetting(int val) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
-    }
-
-    public void setMaximumScreenOffTimeount(int timeMs) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.WRITE_SECURE_SETTINGS, null);
-        synchronized (mLocks) {
-            mMaximumScreenOffTimeout = timeMs;
-            // recalculate everything
-            setScreenOffTimeoutsLocked();
-        }
-    }
-
-    int getStayOnConditionsLocked() {
-        return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE
-                ? mStayOnConditions : 0;
-    }
-
-    private class SettingsObserver implements Observer {
-        private int getInt(String name, int defValue) {
-            ContentValues values = mSettings.getValues(name);
-            Integer iVal = values != null ? values.getAsInteger(Settings.System.VALUE) : null;
-            return iVal != null ? iVal : defValue;
-        }
-
-        private float getFloat(String name, float defValue) {
-            ContentValues values = mSettings.getValues(name);
-            Float fVal = values != null ? values.getAsFloat(Settings.System.VALUE) : null;
-            return fVal != null ? fVal : defValue;
-        }
-
-        public void update(Observable o, Object arg) {
-            synchronized (mLocks) {
-                // STAY_ON_WHILE_PLUGGED_IN, default to when plugged into AC
-                mStayOnConditions = getInt(STAY_ON_WHILE_PLUGGED_IN,
-                        BatteryManager.BATTERY_PLUGGED_AC);
-                updateWakeLockLocked();
-
-                // SCREEN_OFF_TIMEOUT, default to 15 seconds
-                mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
-
-                // DIM_SCREEN
-                //mDimScreen = getInt(DIM_SCREEN) != 0;
-
-                mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
-                mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
-
-                // SCREEN_BRIGHTNESS_MODE, default to manual
-                setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
-                        Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL));
-
-                // recalculate everything
-                setScreenOffTimeoutsLocked();
-
-                mWindowScaleAnimation = getFloat(WINDOW_ANIMATION_SCALE, 1.0f);
-                final float transitionScale = getFloat(TRANSITION_ANIMATION_SCALE, 1.0f);
-                mAnimationSetting = 0;
-                if (mWindowScaleAnimation > 0.5f) {
-                    mAnimationSetting |= ANIM_SETTING_OFF;
-                }
-                if (transitionScale > 0.5f) {
-                    // Uncomment this if you want the screen-on animation.
-                    // mAnimationSetting |= ANIM_SETTING_ON;
-                }
-            }
-        }
-    }
+    static native void nativeSetScreenState(boolean on);
 
     public PowerManagerService() {
-        // Hack to get our uid...  should have a func for this.
-        long token = Binder.clearCallingIdentity();
-        MY_UID = Process.myUid();
-        MY_PID = Process.myPid();
-        Binder.restoreCallingIdentity(token);
-
-        // assume nothing is on yet
-        mUserState = mPowerState = 0;
-
-        // Add ourself to the Watchdog monitors.
-        Watchdog.getInstance().addMonitor(this);
+        synchronized (mLock) {
+            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
+            mWakeLockSuspendBlocker.acquire();
+            mHoldingWakeLockSuspendBlocker = true;
+            mWakefulness = WAKEFULNESS_AWAKE;
+        }
 
         nativeInit();
     }
 
-    private ContentQueryMap mSettings;
-
-    public void init(Context context, LightsService lights, IActivityManager activity,
-            BatteryService battery, DisplayManagerService displayManagerService) {
-        mLightsService = lights;
+    /**
+     * Initialize the power manager.
+     * Must be called before any other functions within the power manager are called.
+     */
+    public void init(Context context, LightsService ls,
+            ActivityManagerService am, BatteryService bs, IBatteryStats bss,
+            DisplayManagerService dm) {
         mContext = context;
-        mActivityService = activity;
-        mBatteryStats = BatteryStatsService.getService();
-        mBatteryService = battery;
-        mDisplayManagerService = displayManagerService;
-
-        mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
-        mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
-        mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
-        mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
-        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
-
-        mInitComplete = false;
-        mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread",
-                Process.THREAD_PRIORITY_DISPLAY);
-        mScreenBrightnessAnimator.start();
-
-        synchronized (mScreenBrightnessAnimator) {
-            while (!mInitComplete) {
-                try {
-                    mScreenBrightnessAnimator.wait();
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-        }
-
-        mInitComplete = false;
-        mHandlerThread = new HandlerThread("PowerManagerService") {
-            @Override
-            protected void onLooperPrepared() {
-                super.onLooperPrepared();
-                initInThread();
-            }
-        };
+        mLightsService = ls;
+        mBatteryService = bs;
+        mBatteryStats = bss;
+        mHandlerThread = new HandlerThread(TAG);
         mHandlerThread.start();
+        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
 
-        synchronized (mHandlerThread) {
-            while (!mInitComplete) {
-                try {
-                    mHandlerThread.wait();
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-        }
+        Watchdog.getInstance().addMonitor(this);
+    }
 
-        synchronized (mLocks) {
-            updateNativePowerStateLocked();
-            // We make sure to start out with the screen on due to user activity.
-            // (They did just boot their device, after all.)
-            forceUserActivityLocked();
-            mInitialized = true;
+    public void setPolicy(WindowManagerPolicy policy) {
+        synchronized (mLock) {
+            mPolicy = policy;
         }
     }
 
-    void initInThread() {
-        mHandler = new Handler();
+    public void systemReady() {
+        synchronized (mLock) {
+            mSystemReady = true;
 
-        mBroadcastWakeLock = new UnsynchronizedWakeLock(
-                                PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
-        mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
-                                PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
-        mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
-                                PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
-        mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
-                                PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
-        mProximityPartialLock = new UnsynchronizedWakeLock(
-                                PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
+            PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
+            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
+            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
 
-        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
-        mScreenOnIntent.addFlags(
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
-        mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
-        mScreenOffIntent.addFlags(
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+            mNotifier = new Notifier(mHandler.getLooper(), mContext, mBatteryStats,
+                    createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
+                    mPolicy, mScreenOnListener);
+            mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
+                    mContext, mNotifier, mLightsService,
+                    createSuspendBlockerLocked("PowerManagerService.Display"),
+                    mDisplayPowerControllerCallbacks, mHandler);
 
-        Resources resources = mContext.getResources();
+            mSettingsObserver = new SettingsObserver(mHandler);
+            mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION);
 
-        mAnimateScreenLights = resources.getBoolean(
-                com.android.internal.R.bool.config_animateScreenLights);
+            // Register for broadcasts from other components of the system.
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+            mContext.registerReceiver(new BatteryReceiver(), filter);
 
-        mUnplugTurnsOnScreen = resources.getBoolean(
+            filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_BOOT_COMPLETED);
+            mContext.registerReceiver(new BootCompletedReceiver(), filter);
+
+            filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_DOCK_EVENT);
+            mContext.registerReceiver(new DockReceiver(), filter);
+
+            // Register for settings changes.
+            final ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.SCREENSAVER_ENABLED), false, mSettingsObserver);
+            resolver.registerContentObserver(Settings.System.getUriFor(
+                    Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver);
+            resolver.registerContentObserver(Settings.System.getUriFor(
+                    Settings.System.STAY_ON_WHILE_PLUGGED_IN), false, mSettingsObserver);
+            resolver.registerContentObserver(Settings.System.getUriFor(
+                    Settings.System.SCREEN_BRIGHTNESS), false, mSettingsObserver);
+            resolver.registerContentObserver(Settings.System.getUriFor(
+                    Settings.System.SCREEN_BRIGHTNESS_MODE), false, mSettingsObserver);
+
+            // Go.
+            readConfigurationLocked();
+            updateSettingsLocked();
+            mDirty |= DIRTY_BATTERY_STATE;
+            updatePowerStateLocked();
+        }
+    }
+
+    private void readConfigurationLocked() {
+        final Resources resources = mContext.getResources();
+
+        mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_unplugTurnsOnScreen);
-
-        mScreenBrightnessDim = resources.getInteger(
-                com.android.internal.R.integer.config_screenBrightnessDim);
-
-        // read settings for auto-brightness
-        mUseSoftwareAutoBrightness = resources.getBoolean(
-                com.android.internal.R.bool.config_automatic_brightness_available);
-        if (mUseSoftwareAutoBrightness) {
-            mAutoBrightnessLevels = resources.getIntArray(
-                    com.android.internal.R.array.config_autoBrightnessLevels);
-            mLcdBacklightValues = resources.getIntArray(
-                    com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
-            mButtonBacklightValues = resources.getIntArray(
-                    com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
-            mKeyboardBacklightValues = resources.getIntArray(
-                    com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
-            mLightSensorWarmupTime = resources.getInteger(
-                    com.android.internal.R.integer.config_lightSensorWarmupTime);
-        }
-
-       ContentResolver resolver = mContext.getContentResolver();
-        Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
-                "(" + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?) or ("
-                        + Settings.System.NAME + "=?)",
-                new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
-                        SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
-                        WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
-                null);
-        mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
-        SettingsObserver settingsObserver = new SettingsObserver();
-        mSettings.addObserver(settingsObserver);
-
-        // pretend that the settings changed so we will get their initial state
-        settingsObserver.update(mSettings, null);
-
-        // register for the battery changed notifications
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        mContext.registerReceiver(new BatteryReceiver(), filter);
-        filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
-        mContext.registerReceiver(new BootCompletedReceiver(), filter);
-        filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_DOCK_EVENT);
-        mContext.registerReceiver(new DockReceiver(), filter);
-
-        // Listen for secure settings changes
-        mContext.getContentResolver().registerContentObserver(
-            Settings.Secure.CONTENT_URI, true,
-            new ContentObserver(new Handler()) {
-                public void onChange(boolean selfChange) {
-                    updateSettingsValues();
-                }
-            });
-        updateSettingsValues();
-
-        synchronized (mHandlerThread) {
-            mInitComplete = true;
-            mHandlerThread.notifyAll();
-        }
+        mDreamsSupportedConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_enableDreams);
     }
 
-    /**
-     * Low-level function turn the device off immediately, without trying
-     * to be clean.  Most people should use
-     * {@link com.android.server.power.internal.app.ShutdownThread} for a clean shutdown.
-     */
-    public static void lowLevelShutdown() {
-        nativeShutdown();
-    }
+    private void updateSettingsLocked() {
+        final ContentResolver resolver = mContext.getContentResolver();
 
-    /**
-     * Low-level function to reboot the device.
-     *
-     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
-     * @throws IOException if reboot fails for some reason (eg, lack of
-     *         permission)
-     */
-    public static void lowLevelReboot(String reason) throws IOException {
-        nativeReboot(reason);
-    }
+        mDreamsEnabledSetting = (Settings.Secure.getInt(resolver,
+                Settings.Secure.SCREENSAVER_ENABLED, 0) != 0);
+        mScreenOffTimeoutSetting = Settings.System.getInt(resolver,
+                Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT);
+        mStayOnWhilePluggedInSetting = Settings.System.getInt(resolver,
+                Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+                BatteryManager.BATTERY_PLUGGED_AC);
 
-    private class WakeLock implements IBinder.DeathRecipient
-    {
-        WakeLock(int f, IBinder b, String t, int u, int p) {
-            super();
-            flags = f;
-            binder = b;
-            tag = t;
-            uid = u == MY_UID ? Process.SYSTEM_UID : u;
-            pid = p;
-            if (u != MY_UID || (
-                    !"KEEP_SCREEN_ON_FLAG".equals(tag)
-                    && !"KeyInputQueue".equals(tag))) {
-                monitorType = (f & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK
-                        ? BatteryStats.WAKE_TYPE_PARTIAL
-                        : BatteryStats.WAKE_TYPE_FULL;
-            } else {
-                monitorType = -1;
-            }
-            try {
-                b.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                binderDied();
-            }
+        final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
+        mScreenBrightnessSetting = Settings.System.getInt(resolver,
+                Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault);
+        if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
+            mTemporaryScreenBrightnessSettingOverride = -1;
         }
-        public void binderDied() {
-            synchronized (mLocks) {
-                releaseWakeLockLocked(this.binder, 0, true);
-            }
-        }
-        final int flags;
-        final IBinder binder;
-        final String tag;
-        final int uid;
-        final int pid;
-        final int monitorType;
-        WorkSource ws;
-        boolean activated = true;
-        int minState;
+
+        mScreenBrightnessModeSetting = Settings.System.getInt(resolver,
+                Settings.System.SCREEN_BRIGHTNESS_MODE,
+                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+
+        mDirty |= DIRTY_SETTINGS;
     }
 
-    private void updateWakeLockLocked() {
-        final int stayOnConditions = getStayOnConditionsLocked();
-        if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
-            // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
-            mStayOnWhilePluggedInScreenDimLock.acquire();
-            mStayOnWhilePluggedInPartialLock.acquire();
+    private void handleSettingsChangedLocked() {
+        updateSettingsLocked();
+        updatePowerStateLocked();
+    }
+
+    @Override // Binder call
+    public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
+        if (lock == null) {
+            throw new IllegalArgumentException("lock must not be null");
+        }
+        PowerManager.validateWakeLockParameters(flags, tag);
+
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
+        if (ws != null && ws.size() != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.UPDATE_DEVICE_STATS, null);
         } else {
-            mStayOnWhilePluggedInScreenDimLock.release();
-            mStayOnWhilePluggedInPartialLock.release();
+            ws = null;
         }
-    }
 
-    private boolean isScreenLock(int flags)
-    {
-        int n = flags & LOCK_MASK;
-        return n == PowerManager.FULL_WAKE_LOCK
-                || n == PowerManager.SCREEN_BRIGHT_WAKE_LOCK
-                || n == PowerManager.SCREEN_DIM_WAKE_LOCK
-                || n == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
-    }
-
-    void enforceWakeSourcePermission(int uid, int pid) {
-        if (uid == Process.myUid()) {
-            return;
-        }
-        mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
-                pid, uid, null);
-    }
-
-    public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
-        int uid = Binder.getCallingUid();
-        int pid = Binder.getCallingPid();
-        if (uid != Process.myUid()) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
-        }
-        if (ws != null) {
-            enforceWakeSourcePermission(uid, pid);
-        }
-        long ident = Binder.clearCallingIdentity();
+        final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
+        final long ident = Binder.clearCallingIdentity();
         try {
-            synchronized (mLocks) {
-                acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
-            }
+            acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
-    void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
-        if (wl.monitorType >= 0) {
-            long origId = Binder.clearCallingIdentity();
-            try {
-                if (ws != null) {
-                    mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
-                            wl.monitorType);
-                } else {
-                    mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
-                }
-            } catch (RemoteException e) {
-                // Ignore
-            } finally {
-                Binder.restoreCallingIdentity(origId);
+    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
+            int uid, int pid) {
+        synchronized (mLock) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
+                        + ", flags=0x" + Integer.toHexString(flags)
+                        + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid);
             }
-        }
-    }
 
-    void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
-        if (wl.monitorType >= 0) {
-            long origId = Binder.clearCallingIdentity();
-            try {
-                if (ws != null) {
-                    mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
-                            wl.monitorType);
-                } else {
-                    mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
-                }
-            } catch (RemoteException e) {
-                // Ignore
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
-            WorkSource ws) {
-        if (DEBUG) {
-            Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
-        }
-
-        if (ws != null && ws.size() == 0) {
-            ws = null;
-        }
-
-        int index = mLocks.getIndex(lock);
-        WakeLock wl;
-        boolean newlock;
-        boolean diffsource;
-        WorkSource oldsource;
-        if (index < 0) {
-            wl = new WakeLock(flags, lock, tag, uid, pid);
-            switch (wl.flags & LOCK_MASK)
-            {
-                case PowerManager.FULL_WAKE_LOCK:
-                    if (mUseSoftwareAutoBrightness) {
-                        wl.minState = SCREEN_BRIGHT;
-                    } else {
-                        wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
-                    }
-                    break;
-                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
-                    wl.minState = SCREEN_BRIGHT;
-                    break;
-                case PowerManager.SCREEN_DIM_WAKE_LOCK:
-                    wl.minState = SCREEN_DIM;
-                    break;
-                case PowerManager.PARTIAL_WAKE_LOCK:
-                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
-                    break;
-                default:
-                    // just log and bail.  we're in the server, so don't
-                    // throw an exception.
-                    Slog.e(TAG, "bad wakelock type for lock '" + tag + "' "
-                            + " flags=" + flags);
-                    return;
-            }
-            mLocks.addLock(wl);
-            if (ws != null) {
-                wl.ws = new WorkSource(ws);
-            }
-            newlock = true;
-            diffsource = false;
-            oldsource = null;
-        } else {
-            wl = mLocks.get(index);
-            newlock = false;
-            oldsource = wl.ws;
-            if (oldsource != null) {
-                if (ws == null) {
-                    wl.ws = null;
-                    diffsource = true;
-                } else {
-                    diffsource = oldsource.diff(ws);
-                }
-            } else if (ws != null) {
-                diffsource = true;
-            } else {
-                diffsource = false;
-            }
-            if (diffsource) {
-                wl.ws = new WorkSource(ws);
-            }
-        }
-        if (isScreenLock(flags)) {
-            // if this causes a wakeup, we reactivate all of the locks and
-            // set it to whatever they want.  otherwise, we modulate that
-            // by the current state so we never turn it more on than
-            // it already is.
-            if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
-                mProximityWakeLockCount++;
-                if (mProximityWakeLockCount == 1) {
-                    enableProximityLockLocked();
+            WakeLock wakeLock;
+            int index = findWakeLockIndexLocked(lock);
+            if (index >= 0) {
+                wakeLock = mWakeLocks.get(index);
+                if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
+                    // Update existing wake lock.  This shouldn't happen but is harmless.
+                    notifyWakeLockReleasedLocked(wakeLock);
+                    wakeLock.updateProperties(flags, tag, ws, uid, pid);
+                    notifyWakeLockAcquiredLocked(wakeLock);
                 }
             } else {
-                if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
-                    int oldWakeLockState = mWakeLockState;
-                    mWakeLockState = mLocks.reactivateScreenLocksLocked();
-
-                    // Disable proximity sensor if if user presses power key while we are in the
-                    // "waiting for proximity sensor to go negative" state.
-                    if ((mWakeLockState & SCREEN_ON_BIT) != 0
-                            && mProximitySensorActive && mProximityWakeLockCount == 0) {
-                        mProximitySensorActive = false;
-                    }
-
-                    if (DEBUG) {
-                        Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)
-                                + " mWakeLockState=0x"
-                                + Integer.toHexString(mWakeLockState)
-                                + " previous wakeLockState=0x"
-                                + Integer.toHexString(oldWakeLockState));
-                    }
-                } else {
-                    if (DEBUG) {
-                        Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)
-                                + " mLocks.gatherState()=0x"
-                                + Integer.toHexString(mLocks.gatherState())
-                                + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));
-                    }
-                    mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();
+                wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
+                try {
+                    lock.linkToDeath(wakeLock, 0);
+                } catch (RemoteException ex) {
+                    throw new IllegalArgumentException("Wake lock is already dead.");
                 }
-                setPowerState(mWakeLockState | mUserState);
+                notifyWakeLockAcquiredLocked(wakeLock);
+                mWakeLocks.add(wakeLock);
             }
-        }
-        else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
-            if (newlock) {
-                mPartialCount++;
-                if (mPartialCount == 1) {
-                    if (LOG_PARTIAL_WL) {
-                        EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);
-                    }
-                }
-            }
-            nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME);
-        }
 
-        if (diffsource) {
-            // If the lock sources have changed, need to first release the
-            // old ones.
-            noteStopWakeLocked(wl, oldsource);
-        }
-        if (newlock || diffsource) {
-            noteStartWakeLocked(wl, ws);
+            applyWakeLockFlagsOnAcquireLocked(wakeLock);
+            mDirty |= DIRTY_WAKE_LOCKS;
+            updatePowerStateLocked();
         }
     }
 
-    public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
-        int uid = Binder.getCallingUid();
-        int pid = Binder.getCallingPid();
-        if (ws != null && ws.size() == 0) {
-            ws = null;
-        }
-        if (ws != null) {
-            enforceWakeSourcePermission(uid, pid);
-        }
-        synchronized (mLocks) {
-            int index = mLocks.getIndex(lock);
-            if (index < 0) {
-                throw new IllegalArgumentException("Wake lock not active");
-            }
-            WakeLock wl = mLocks.get(index);
-            WorkSource oldsource = wl.ws;
-            wl.ws = ws != null ? new WorkSource(ws) : null;
-            noteStopWakeLocked(wl, oldsource);
-            noteStartWakeLocked(wl, ws);
+    private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
+        if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
+            wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
         }
     }
 
+    @Override // Binder call
     public void releaseWakeLock(IBinder lock, int flags) {
-        int uid = Binder.getCallingUid();
-        if (uid != Process.myUid()) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
+        if (lock == null) {
+            throw new IllegalArgumentException("lock must not be null");
         }
 
-        synchronized (mLocks) {
-            releaseWakeLockLocked(lock, flags, false);
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            releaseWakeLockInternal(lock, flags);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
-        WakeLock wl = mLocks.removeLock(lock);
-        if (wl == null) {
-            return;
-        }
-
-        if (DEBUG) {
-            Slog.d(TAG, "releaseWakeLock flags=0x"
-                    + Integer.toHexString(wl.flags) + " tag=" + wl.tag);
-        }
-
-        if (isScreenLock(wl.flags)) {
-            if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
-                mProximityWakeLockCount--;
-                if (mProximityWakeLockCount == 0) {
-                    if (mProximitySensorActive &&
-                            ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0)) {
-                        // wait for proximity sensor to go negative before disabling sensor
-                        if (DEBUG_PROXIMITY_SENSOR) {
-                            Slog.d(TAG, "waiting for proximity sensor to go negative");
-                        }
-                    } else {
-                        disableProximityLockLocked();
-                    }
-                }
-            } else {
-                mWakeLockState = mLocks.gatherState();
-                // goes in the middle to reduce flicker
-                if ((wl.flags & PowerManager.ON_AFTER_RELEASE) != 0) {
-                    userActivity(SystemClock.uptimeMillis(), -1, false, PowerManager.USER_ACTIVITY_EVENT_OTHER, false, true);
-                }
-                setPowerState(mWakeLockState | mUserState);
-            }
-        }
-        else if ((wl.flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {
-            mPartialCount--;
-            if (mPartialCount == 0) {
-                if (LOG_PARTIAL_WL) {
-                    EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
-                }
-                nativeReleaseWakeLock(PARTIAL_NAME);
-            }
-        }
-        // Unlink the lock from the binder.
-        wl.binder.unlinkToDeath(wl, 0);
-
-        noteStopWakeLocked(wl, wl.ws);
-    }
-
-    private class PokeLock implements IBinder.DeathRecipient
-    {
-        PokeLock(int p, IBinder b, String t) {
-            super();
-            this.pokey = p;
-            this.binder = b;
-            this.tag = t;
-            try {
-                b.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                binderDied();
-            }
-        }
-        public void binderDied() {
-            setPokeLock(0, this.binder, this.tag);
-        }
-        int pokey;
-        IBinder binder;
-        String tag;
-        boolean awakeOnSet;
-    }
-
-    public void setPokeLock(int pokey, IBinder token, String tag) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        if (token == null) {
-            Slog.e(TAG, "setPokeLock got null token for tag='" + tag + "'");
-            return;
-        }
-
-        if ((pokey & POKE_LOCK_TIMEOUT_MASK) == POKE_LOCK_TIMEOUT_MASK) {
-            throw new IllegalArgumentException("setPokeLock can't have both POKE_LOCK_SHORT_TIMEOUT"
-                    + " and POKE_LOCK_MEDIUM_TIMEOUT");
-        }
-
-        synchronized (mLocks) {
-            if (pokey != 0) {
-                PokeLock p = mPokeLocks.get(token);
-                int oldPokey = 0;
-                if (p != null) {
-                    oldPokey = p.pokey;
-                    p.pokey = pokey;
-                } else {
-                    p = new PokeLock(pokey, token, tag);
-                    mPokeLocks.put(token, p);
-                }
-                int oldTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
-                int newTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
-                if (((mPowerState & SCREEN_ON_BIT) == 0) && (oldTimeout != newTimeout)) {
-                    p.awakeOnSet = true;
-                }
-            } else {
-                PokeLock rLock = mPokeLocks.remove(token);
-                if (rLock != null) {
-                    token.unlinkToDeath(rLock, 0);
-                }
+    private void releaseWakeLockInternal(IBinder lock, int flags) {
+        synchronized (mLock) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
+                        + ", flags=0x" + Integer.toHexString(flags));
             }
 
-            int oldPokey = mPokey;
-            int cumulative = 0;
-            boolean awakeOnSet = false;
-            for (PokeLock p: mPokeLocks.values()) {
-                cumulative |= p.pokey;
-                if (p.awakeOnSet) {
-                    awakeOnSet = true;
-                }
-            }
-            mPokey = cumulative;
-            mPokeAwakeOnSet = awakeOnSet;
-
-            int oldCumulativeTimeout = oldPokey & POKE_LOCK_TIMEOUT_MASK;
-            int newCumulativeTimeout = pokey & POKE_LOCK_TIMEOUT_MASK;
-
-            if (oldCumulativeTimeout != newCumulativeTimeout) {
-                setScreenOffTimeoutsLocked();
-                // reset the countdown timer, but use the existing nextState so it doesn't
-                // change anything
-                setTimeoutLocked(SystemClock.uptimeMillis(), mTimeoutTask.nextState);
-            }
-        }
-    }
-
-    private static String lockType(int type)
-    {
-        switch (type)
-        {
-            case PowerManager.FULL_WAKE_LOCK:
-                return "FULL_WAKE_LOCK                ";
-            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
-                return "SCREEN_BRIGHT_WAKE_LOCK       ";
-            case PowerManager.SCREEN_DIM_WAKE_LOCK:
-                return "SCREEN_DIM_WAKE_LOCK          ";
-            case PowerManager.PARTIAL_WAKE_LOCK:
-                return "PARTIAL_WAKE_LOCK             ";
-            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
-                return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
-            default:
-                return "???                           ";
-        }
-    }
-
-    private static String dumpPowerState(int state) {
-        return (((state & KEYBOARD_BRIGHT_BIT) != 0)
-                        ? "KEYBOARD_BRIGHT_BIT " : "")
-                + (((state & SCREEN_BRIGHT_BIT) != 0)
-                        ? "SCREEN_BRIGHT_BIT " : "")
-                + (((state & SCREEN_ON_BIT) != 0)
-                        ? "SCREEN_ON_BIT " : "")
-                + (((state & BUTTON_BRIGHT_BIT) != 0)
-                        ? "BUTTON_BRIGHT_BIT " : "")
-                + (((state & BATTERY_LOW_BIT) != 0)
-                        ? "BATTERY_LOW_BIT " : "");
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump PowerManager from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-
-        long now = SystemClock.uptimeMillis();
-
-        synchronized (mLocks) {
-            pw.println("Power Manager State:");
-            pw.println("  mIsPowered=" + mIsPowered
-                    + " mPowerState=" + mPowerState
-                    + " mScreenOffTime=" + (SystemClock.elapsedRealtime()-mScreenOffTime)
-                    + " ms");
-            pw.println("  mPartialCount=" + mPartialCount);
-            pw.println("  mWakeLockState=" + dumpPowerState(mWakeLockState));
-            pw.println("  mUserState=" + dumpPowerState(mUserState));
-            pw.println("  mPowerState=" + dumpPowerState(mPowerState));
-            pw.println("  mLocks.gather=" + dumpPowerState(mLocks.gatherState()));
-            pw.println("  mNextTimeout=" + mNextTimeout + " now=" + now
-                    + " " + ((mNextTimeout-now)/1000) + "s from now");
-            pw.println("  mDimScreen=" + mDimScreen
-                    + " mStayOnConditions=" + mStayOnConditions
-                    + " mPreparingForScreenOn=" + mPreparingForScreenOn
-                    + " mSkippedScreenOn=" + mSkippedScreenOn);
-            pw.println("  mScreenOffReason=" + mScreenOffReason
-                    + " mUserState=" + mUserState);
-            pw.println("  mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
-                    + ',' + mBroadcastQueue[2] + "}");
-            pw.println("  mBroadcastWhy={" + mBroadcastWhy[0] + ',' + mBroadcastWhy[1]
-                    + ',' + mBroadcastWhy[2] + "}");
-            pw.println("  mPokey=" + mPokey + " mPokeAwakeonSet=" + mPokeAwakeOnSet);
-            pw.println("  mKeyboardVisible=" + mKeyboardVisible
-                    + " mUserActivityAllowed=" + mUserActivityAllowed);
-            pw.println("  mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
-                    + " mScreenOffDelay=" + mScreenOffDelay);
-            pw.println("  mPreventScreenOn=" + mPreventScreenOn
-                    + "  mScreenBrightnessOverride=" + mScreenBrightnessOverride
-                    + "  mButtonBrightnessOverride=" + mButtonBrightnessOverride);
-            pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting
-                    + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout);
-            pw.println("  mLastScreenOnTime=" + mLastScreenOnTime);
-            pw.println("  mBroadcastWakeLock=" + mBroadcastWakeLock);
-            pw.println("  mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
-            pw.println("  mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock);
-            pw.println("  mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock);
-            pw.println("  mProximityPartialLock=" + mProximityPartialLock);
-            pw.println("  mProximityWakeLockCount=" + mProximityWakeLockCount);
-            pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
-            pw.println("  mProximitySensorActive=" + mProximitySensorActive);
-            pw.println("  mProximityPendingValue=" + mProximityPendingValue);
-            pw.println("  mLastProximityEventTime=" + mLastProximityEventTime);
-            pw.println("  mLightSensorEnabled=" + mLightSensorEnabled
-                    + " mLightSensorAdjustSetting=" + mLightSensorAdjustSetting);
-            pw.println("  mLightSensorValue=" + mLightSensorValue
-                    + " mLightSensorPendingValue=" + mLightSensorPendingValue);
-            pw.println("  mHighestLightSensorValue=" + mHighestLightSensorValue
-                    + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
-            pw.println("  mLightSensorPendingDecrease=" + mLightSensorPendingDecrease
-                    + " mLightSensorPendingIncrease=" + mLightSensorPendingIncrease);
-            pw.println("  mLightSensorScreenBrightness=" + mLightSensorScreenBrightness
-                    + " mLightSensorButtonBrightness=" + mLightSensorButtonBrightness
-                    + " mLightSensorKeyboardBrightness=" + mLightSensorKeyboardBrightness);
-            pw.println("  mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
-            pw.println("  mAutoBrightessEnabled=" + mAutoBrightessEnabled);
-            mScreenBrightnessAnimator.dump(pw, "mScreenBrightnessAnimator: ");
-
-            int N = mLocks.size();
-            pw.println();
-            pw.println("mLocks.size=" + N + ":");
-            for (int i=0; i<N; i++) {
-                WakeLock wl = mLocks.get(i);
-                String type = lockType(wl.flags & LOCK_MASK);
-                String acquireCausesWakeup = "";
-                if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
-                    acquireCausesWakeup = "ACQUIRE_CAUSES_WAKEUP ";
-                }
-                String activated = "";
-                if (wl.activated) {
-                   activated = " activated";
-                }
-                pw.println("  " + type + " '" + wl.tag + "'" + acquireCausesWakeup
-                        + activated + " (minState=" + wl.minState + ", uid=" + wl.uid
-                        + ", pid=" + wl.pid + ")");
-            }
-
-            pw.println();
-            pw.println("mPokeLocks.size=" + mPokeLocks.size() + ":");
-            for (PokeLock p: mPokeLocks.values()) {
-                pw.println("    poke lock '" + p.tag + "':"
-                        + ((p.pokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0
-                                ? " POKE_LOCK_IGNORE_TOUCH_EVENTS" : "")
-                        + ((p.pokey & POKE_LOCK_SHORT_TIMEOUT) != 0
-                                ? " POKE_LOCK_SHORT_TIMEOUT" : "")
-                        + ((p.pokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0
-                                ? " POKE_LOCK_MEDIUM_TIMEOUT" : ""));
-            }
-
-            pw.println();
-        }
-    }
-
-    private void setTimeoutLocked(long now, int nextState) {
-        setTimeoutLocked(now, -1, nextState);
-    }
-
-    // If they gave a timeoutOverride it is the number of seconds
-    // to screen-off.  Figure out where in the countdown cycle we
-    // should jump to.
-    private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {
-        long timeoutOverride = originalTimeoutOverride;
-        if (mBootCompleted) {
-            synchronized (mLocks) {
-                long when = 0;
-                if (timeoutOverride <= 0) {
-                    switch (nextState)
-                    {
-                        case SCREEN_BRIGHT:
-                            when = now + mKeylightDelay;
-                            break;
-                        case SCREEN_DIM:
-                            if (mDimDelay >= 0) {
-                                when = now + mDimDelay;
-                                break;
-                            } else {
-                                Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");
-                            }
-                       case SCREEN_OFF:
-                            synchronized (mLocks) {
-                                when = now + mScreenOffDelay;
-                            }
-                            break;
-                        default:
-                            when = now;
-                            break;
-                    }
-                } else {
-                    override: {
-                        if (timeoutOverride <= mScreenOffDelay) {
-                            when = now + timeoutOverride;
-                            nextState = SCREEN_OFF;
-                            break override;
-                        }
-                        timeoutOverride -= mScreenOffDelay;
-
-                        if (mDimDelay >= 0) {
-                             if (timeoutOverride <= mDimDelay) {
-                                when = now + timeoutOverride;
-                                nextState = SCREEN_DIM;
-                                break override;
-                            }
-                            timeoutOverride -= mDimDelay;
-                        }
-
-                        when = now + timeoutOverride;
-                        nextState = SCREEN_BRIGHT;
-                    }
-                }
-                if (DEBUG) {
-                    Slog.d(TAG, "setTimeoutLocked now=" + now
-                            + " timeoutOverride=" + timeoutOverride
-                            + " nextState=" + nextState + " when=" + when);
-                }
-
-                mHandler.removeCallbacks(mTimeoutTask);
-                mTimeoutTask.nextState = nextState;
-                mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0
-                        ? (originalTimeoutOverride - timeoutOverride)
-                        : -1;
-                mHandler.postAtTime(mTimeoutTask, when);
-                mNextTimeout = when; // for debugging
-            }
-        }
-    }
-
-    private void cancelTimerLocked()
-    {
-        mHandler.removeCallbacks(mTimeoutTask);
-        mTimeoutTask.nextState = -1;
-    }
-
-    private class TimeoutTask implements Runnable
-    {
-        int nextState; // access should be synchronized on mLocks
-        long remainingTimeoutOverride;
-        public void run()
-        {
-            synchronized (mLocks) {
-                if (DEBUG) {
-                    Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);
-                }
-
-                if (nextState == -1) {
-                    return;
-                }
-
-                mUserState = this.nextState;
-                setPowerState(this.nextState | mWakeLockState);
-
-                long now = SystemClock.uptimeMillis();
-
-                switch (this.nextState)
-                {
-                    case SCREEN_BRIGHT:
-                        if (mDimDelay >= 0) {
-                            setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);
-                            break;
-                        }
-                    case SCREEN_DIM:
-                        setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);
-                        break;
-                }
-            }
-        }
-    }
-
-    private void sendNotificationLocked(boolean on, int why) {
-        if (!mInitialized) {
-            // No notifications sent until first initialization is done.
-            // This is so that when we are moving from our initial state
-            // which looks like the screen was off to it being on, we do not
-            // go through the process of waiting for the higher-level user
-            // space to be ready before turning up the display brightness.
-            // (And also do not send needless broadcasts about the screen.)
-            return;
-        }
-
-        if (DEBUG_SCREEN_ON) {
-            RuntimeException here = new RuntimeException("here");
-            here.fillInStackTrace();
-            Slog.i(TAG, "sendNotificationLocked: " + on, here);
-        }
-
-        if (!on) {
-            mStillNeedSleepNotification = false;
-        }
-
-        // Add to the queue.
-        int index = 0;
-        while (mBroadcastQueue[index] != -1) {
-            index++;
-        }
-        mBroadcastQueue[index] = on ? 1 : 0;
-        mBroadcastWhy[index] = why;
-
-        // If we added it position 2, then there is a pair that can be stripped.
-        // If we added it position 1 and we're turning the screen off, we can strip
-        // the pair and do nothing, because the screen is already off, and therefore
-        // keyguard has already been enabled.
-        // However, if we added it at position 1 and we're turning it on, then position
-        // 0 was to turn it off, and we can't strip that, because keyguard needs to come
-        // on, so have to run the queue then.
-        if (index == 2) {
-            // While we're collapsing them, if it's going off, and the new reason
-            // is more significant than the first, then use the new one.
-            if (!on && mBroadcastWhy[0] > why) {
-                mBroadcastWhy[0] = why;
-            }
-            mBroadcastQueue[0] = on ? 1 : 0;
-            mBroadcastQueue[1] = -1;
-            mBroadcastQueue[2] = -1;
-            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
-            mBroadcastWakeLock.release();
-            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
-            mBroadcastWakeLock.release();
-            index = 0;
-        }
-        if (index == 1 && !on) {
-            mBroadcastQueue[0] = -1;
-            mBroadcastQueue[1] = -1;
-            index = -1;
-            // The wake lock was being held, but we're not actually going to do any
-            // broadcasts, so release the wake lock.
-            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
-            mBroadcastWakeLock.release();
-        }
-
-        // The broadcast queue has changed; make sure the screen is on if it
-        // is now possible for it to be.
-        if (mSkippedScreenOn) {
-            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
-        }
-
-        // Now send the message.
-        if (index >= 0) {
-            // Acquire the broadcast wake lock before changing the power
-            // state. It will be release after the broadcast is sent.
-            // We always increment the ref count for each notification in the queue
-            // and always decrement when that notification is handled.
-            mBroadcastWakeLock.acquire();
-            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, mBroadcastWakeLock.mCount);
-            mHandler.post(mNotificationTask);
-        }
-    }
-
-    private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
-            new WindowManagerPolicy.ScreenOnListener() {
-                public void onScreenOn() {
-                    synchronized (mLocks) {
-                        if (mPreparingForScreenOn) {
-                            mPreparingForScreenOn = false;
-                            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
-                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
-                                    4, mBroadcastWakeLock.mCount);
-                            mBroadcastWakeLock.release();
-                        }
-                    }
-                }
-    };
-
-    private Runnable mNotificationTask = new Runnable()
-    {
-        public void run()
-        {
-            while (true) {
-                int value;
-                int why;
-                WindowManagerPolicy policy;
-                synchronized (mLocks) {
-                    value = mBroadcastQueue[0];
-                    why = mBroadcastWhy[0];
-                    for (int i=0; i<2; i++) {
-                        mBroadcastQueue[i] = mBroadcastQueue[i+1];
-                        mBroadcastWhy[i] = mBroadcastWhy[i+1];
-                    }
-                    policy = getPolicyLocked();
-                    if (value == 1 && !mPreparingForScreenOn) {
-                        mPreparingForScreenOn = true;
-                        mBroadcastWakeLock.acquire();
-                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
-                                mBroadcastWakeLock.mCount);
-                    }
-                }
-                if (value == 1) {
-                    mScreenOnStart = SystemClock.uptimeMillis();
-
-                    policy.screenTurningOn(mScreenOnListener);
-                    try {
-                        ActivityManagerNative.getDefault().wakingUp();
-                    } catch (RemoteException e) {
-                        // ignore it
-                    }
-
-                    if (DEBUG) {
-                        Slog.d(TAG, "mBroadcastWakeLock=" + mBroadcastWakeLock);
-                    }
-                    if (mContext != null && ActivityManagerNative.isSystemReady()) {
-                        mContext.sendOrderedBroadcast(mScreenOnIntent, null,
-                                mScreenOnBroadcastDone, mHandler, 0, null, null);
-                    } else {
-                        synchronized (mLocks) {
-                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2,
-                                    mBroadcastWakeLock.mCount);
-                            mBroadcastWakeLock.release();
-                        }
-                    }
-                }
-                else if (value == 0) {
-                    mScreenOffStart = SystemClock.uptimeMillis();
-
-                    policy.screenTurnedOff(why);
-                    try {
-                        ActivityManagerNative.getDefault().goingToSleep();
-                    } catch (RemoteException e) {
-                        // ignore it.
-                    }
-
-                    if (mContext != null && ActivityManagerNative.isSystemReady()) {
-                        mContext.sendOrderedBroadcast(mScreenOffIntent, null,
-                                mScreenOffBroadcastDone, mHandler, 0, null, null);
-                    } else {
-                        synchronized (mLocks) {
-                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
-                                    mBroadcastWakeLock.mCount);
-                            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
-                            mBroadcastWakeLock.release();
-                        }
-                    }
-                }
-                else {
-                    // If we're in this case, then this handler is running for a previous
-                    // paired transaction.  mBroadcastWakeLock will already have been released.
-                    break;
-                }
-            }
-        }
-    };
-
-    long mScreenOnStart;
-    private BroadcastReceiver mScreenOnBroadcastDone = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            synchronized (mLocks) {
-                EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
-                        SystemClock.uptimeMillis() - mScreenOnStart, mBroadcastWakeLock.mCount);
-                mBroadcastWakeLock.release();
-            }
-        }
-    };
-
-    long mScreenOffStart;
-    private BroadcastReceiver mScreenOffBroadcastDone = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            synchronized (mLocks) {
-                EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
-                        SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
-                mBroadcastWakeLock.release();
-            }
-        }
-    };
-
-    /**
-     * Prevents the screen from turning on even if it *should* turn on due
-     * to a subsequent full wake lock being acquired.
-     * <p>
-     * This is a temporary hack that allows an activity to "cover up" any
-     * display glitches that happen during the activity's startup
-     * sequence.  (Specifically, this API was added to work around a
-     * cosmetic bug in the "incoming call" sequence, where the lock screen
-     * would flicker briefly before the incoming call UI became visible.)
-     * TODO: There ought to be a more elegant way of doing this,
-     * probably by having the PowerManager and ActivityManager
-     * work together to let apps specify that the screen on/off
-     * state should be synchronized with the Activity lifecycle.
-     * <p>
-     * Note that calling preventScreenOn(true) will NOT turn the screen
-     * off if it's currently on.  (This API only affects *future*
-     * acquisitions of full wake locks.)
-     * But calling preventScreenOn(false) WILL turn the screen on if
-     * it's currently off because of a prior preventScreenOn(true) call.
-     * <p>
-     * Any call to preventScreenOn(true) MUST be followed promptly by a call
-     * to preventScreenOn(false).  In fact, if the preventScreenOn(false)
-     * call doesn't occur within 5 seconds, we'll turn the screen back on
-     * ourselves (and log a warning about it); this prevents a buggy app
-     * from disabling the screen forever.)
-     * <p>
-     * TODO: this feature should really be controlled by a new type of poke
-     * lock (rather than an IPowerManager call).
-     */
-    public void preventScreenOn(boolean prevent) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-
-        synchronized (mLocks) {
-            if (prevent) {
-                // First of all, grab a partial wake lock to
-                // make sure the CPU stays on during the entire
-                // preventScreenOn(true) -> preventScreenOn(false) sequence.
-                mPreventScreenOnPartialLock.acquire();
-
-                // Post a forceReenableScreen() call (for 5 seconds in the
-                // future) to make sure the matching preventScreenOn(false) call
-                // has happened by then.
-                mHandler.removeCallbacks(mForceReenableScreenTask);
-                mHandler.postDelayed(mForceReenableScreenTask, 5000);
-
-                // Finally, set the flag that prevents the screen from turning on.
-                // (Below, in setPowerState(), we'll check mPreventScreenOn and
-                // we *won't* call setScreenStateLocked(true) if it's set.)
-                mPreventScreenOn = true;
-            } else {
-                // (Re)enable the screen.
-                mPreventScreenOn = false;
-
-                // We're "undoing" a the prior preventScreenOn(true) call, so we
-                // no longer need the 5-second safeguard.
-                mHandler.removeCallbacks(mForceReenableScreenTask);
-
-                // Forcibly turn on the screen if it's supposed to be on.  (This
-                // handles the case where the screen is currently off because of
-                // a prior preventScreenOn(true) call.)
-                if (!mProximitySensorActive && (mPowerState & SCREEN_ON_BIT) != 0) {
-                    if (DEBUG) {
-                        Slog.d(TAG,
-                              "preventScreenOn: turning on after a prior preventScreenOn(true)!");
-                    }
-                    int err = setScreenStateLocked(true);
-                    if (err != 0) {
-                        Slog.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
-                    }
-                }
-
-                // Release the partial wake lock that we held during the
-                // preventScreenOn(true) -> preventScreenOn(false) sequence.
-                mPreventScreenOnPartialLock.release();
-            }
-        }
-    }
-
-    public void setScreenBrightnessOverride(int brightness) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-
-        if (DEBUG) Slog.d(TAG, "setScreenBrightnessOverride " + brightness);
-        synchronized (mLocks) {
-            if (mScreenBrightnessOverride != brightness) {
-                mScreenBrightnessOverride = brightness;
-                if (isScreenOn()) {
-                    updateLightsLocked(mPowerState, SCREEN_ON_BIT);
-                }
-            }
-        }
-    }
-
-    public void setButtonBrightnessOverride(int brightness) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-
-        if (DEBUG) Slog.d(TAG, "setButtonBrightnessOverride " + brightness);
-         synchronized (mLocks) {
-           if (mButtonBrightnessOverride != brightness) {
-                mButtonBrightnessOverride = brightness;
-                if (isScreenOn()) {
-                    updateLightsLocked(mPowerState, BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sanity-check that gets called 5 seconds after any call to
-     * preventScreenOn(true).  This ensures that the original call
-     * is followed promptly by a call to preventScreenOn(false).
-     */
-    private void forceReenableScreen() {
-        // We shouldn't get here at all if mPreventScreenOn is false, since
-        // we should have already removed any existing
-        // mForceReenableScreenTask messages...
-        if (!mPreventScreenOn) {
-            Slog.w(TAG, "forceReenableScreen: mPreventScreenOn is false, nothing to do");
-            return;
-        }
-
-        // Uh oh.  It's been 5 seconds since a call to
-        // preventScreenOn(true) and we haven't re-enabled the screen yet.
-        // This means the app that called preventScreenOn(true) is either
-        // slow (i.e. it took more than 5 seconds to call preventScreenOn(false)),
-        // or buggy (i.e. it forgot to call preventScreenOn(false), or
-        // crashed before doing so.)
-
-        // Log a warning, and forcibly turn the screen back on.
-        Slog.w(TAG, "App called preventScreenOn(true) but didn't promptly reenable the screen! "
-              + "Forcing the screen back on...");
-        preventScreenOn(false);
-    }
-
-    private Runnable mForceReenableScreenTask = new Runnable() {
-            public void run() {
-                forceReenableScreen();
-            }
-        };
-
-    private int setScreenStateLocked(boolean on) {
-        if (DEBUG_SCREEN_ON) {
-            RuntimeException e = new RuntimeException("here");
-            e.fillInStackTrace();
-            Slog.i(TAG, "Set screen state: " + on, e);
-        }
-        if (on) {
-            if (mInitialized && ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn)) {
-                // If we are turning the screen state on, but the screen
-                // light is currently off, then make sure that we set the
-                // light at this point to 0.  This is the case where we are
-                // turning on the screen and waiting for the UI to be drawn
-                // before showing it to the user.  We want the light off
-                // until it is ready to be shown to the user, not it using
-                // whatever the last value it had.
-                // Skip this if the screen is being turned on for the first time
-                // after boot (mInitialized is false).
-                if (DEBUG_SCREEN_ON) {
-                    Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
-                            + Integer.toHexString(mPowerState)
-                            + " mSkippedScreenOn=" + mSkippedScreenOn);
-                }
-                mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0);
-            }
-        }
-        int err = nativeSetScreenState(on);
-        if (err == 0) {
-            mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
-            if (mUseSoftwareAutoBrightness) {
-                enableLightSensorLocked(on);
-                if (on) {
-                    // If AutoBrightness is enabled, set the brightness immediately after the
-                    // next sensor value is received.
-                    mWaitingForFirstLightSensor = mAutoBrightessEnabled;
-                } else {
-                    // make sure button and key backlights are off too
-                    mButtonLight.turnOff();
-                    mKeyboardLight.turnOff();
-                }
-            }
-        }
-        return err;
-    }
-
-    private void setPowerState(int state)
-    {
-        setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
-    }
-
-    private void setPowerState(int newState, boolean noChangeLights, int reason)
-    {
-        synchronized (mLocks) {
-            int err;
-
-            if (DEBUG) {
-                Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
-                        + " newState=0x" + Integer.toHexString(newState)
-                        + " noChangeLights=" + noChangeLights
-                        + " reason=" + reason);
-            }
-            
-            if (noChangeLights) {
-                newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);
-            }
-            if (mProximitySensorActive) {
-                // don't turn on the screen when the proximity sensor lock is held
-                newState = (newState & ~SCREEN_BRIGHT);
-            }
-
-            if (batteryIsLow()) {
-                newState |= BATTERY_LOW_BIT;
-            } else {
-                newState &= ~BATTERY_LOW_BIT;
-            }
-            if (newState == mPowerState && mInitialized) {
+            int index = findWakeLockIndexLocked(lock);
+            if (index < 0) {
                 return;
             }
 
-            if (!mBootCompleted && !mUseSoftwareAutoBrightness) {
-                newState |= ALL_BRIGHT;
+            WakeLock wakeLock = mWakeLocks.get(index);
+            mWakeLocks.remove(index);
+            notifyWakeLockReleasedLocked(wakeLock);
+            wakeLock.mLock.unlinkToDeath(wakeLock, 0);
+
+            if ((flags & PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE) != 0) {
+                mRequestWaitForNegativeProximity = true;
             }
 
-            boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;
-            boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;
-
-            if (DEBUG) {
-                Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState
-                        + " newState=" + newState + " noChangeLights=" + noChangeLights);
-                Slog.d(TAG, "  oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)
-                         + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));
-                Slog.d(TAG, "  oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)
-                         + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));
-                Slog.d(TAG, "  oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)
-                         + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));
-                Slog.d(TAG, "  oldScreenOn=" + oldScreenOn
-                         + " newScreenOn=" + newScreenOn);
-                Slog.d(TAG, "  oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)
-                         + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
-            }
-
-            final boolean stateChanged = mPowerState != newState;
-
-            if (stateChanged && !newScreenOn && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
-                if (mPolicy != null && mIsPowered && mPolicy.isScreenSaverEnabled()) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
-                    }
-                    if (mPolicy.startScreenSaver()) {
-                        // was successful
-                        return;
-                    }
-                }
-            }
-
-
-            if (oldScreenOn != newScreenOn) {
-                if (newScreenOn) {
-                    // When the user presses the power button, we need to always send out the
-                    // notification that it's going to sleep so the keyguard goes on.  But
-                    // we can't do that until the screen fades out, so we don't show the keyguard
-                    // too early.
-                    if (mStillNeedSleepNotification) {
-                        sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
-                    }
-
-                    // Turn on the screen UNLESS there was a prior
-                    // preventScreenOn(true) request.  (Note that the lifetime
-                    // of a single preventScreenOn() request is limited to 5
-                    // seconds to prevent a buggy app from disabling the
-                    // screen forever; see forceReenableScreen().)
-                    boolean reallyTurnScreenOn = true;
-                    if (DEBUG) {
-                        Slog.d(TAG, "- turning screen on...  mPreventScreenOn = "
-                              + mPreventScreenOn);
-                    }
-
-                    if (mPreventScreenOn) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "- PREVENTING screen from really turning on!");
-                        }
-                        reallyTurnScreenOn = false;
-                    }
-                    if (reallyTurnScreenOn) {
-                        err = setScreenStateLocked(true);
-                        long identity = Binder.clearCallingIdentity();
-                        try {
-                            mBatteryStats.noteScreenBrightness(getPreferredBrightness());
-                            mBatteryStats.noteScreenOn();
-                        } catch (RemoteException e) {
-                            Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    } else {
-                        setScreenStateLocked(false);
-                        // But continue as if we really did turn the screen on...
-                        err = 0;
-                    }
-
-                    EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason, 0, 0);
-                    if (err == 0) {
-                        sendNotificationLocked(true, -1);
-                        // Update the lights *after* taking care of turning the
-                        // screen on, so we do this after our notifications are
-                        // enqueued and thus will delay turning on the screen light
-                        // until the windows are correctly displayed.
-                        if (stateChanged) {
-                            updateLightsLocked(newState, 0);
-                        }
-                        mPowerState |= SCREEN_ON_BIT;
-                    }
-
-                } else {
-                    // Update the lights *before* taking care of turning the
-                    // screen off, so we can initiate any animations that are desired.
-                    mScreenOffReason = reason;
-                    if (stateChanged) {
-                        updateLightsLocked(newState, 0);
-                    }
-
-                    // cancel light sensor task
-                    mHandler.removeCallbacks(mAutoBrightnessTask);
-                    mLightSensorPendingDecrease = false;
-                    mLightSensorPendingIncrease = false;
-                    mScreenOffTime = SystemClock.elapsedRealtime();
-                    long identity = Binder.clearCallingIdentity();
-                    try {
-                        mBatteryStats.noteScreenOff();
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                    mPowerState &= ~SCREEN_ON_BIT;
-                    if (!mScreenBrightnessAnimator.isAnimating()) {
-                        err = screenOffFinishedAnimatingLocked(reason);
-                    } else {
-                        err = 0;
-                    }
-
-                    // stop the screensaver if user turned screen off
-                    if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
-                        if (mPolicy != null) {
-                            mPolicy.stopScreenSaver();
-                        }
-                    }
-                }
-            } else if (stateChanged) {
-                // Screen on/off didn't change, but lights may have.
-                updateLightsLocked(newState, 0);
-            }
-
-            mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
-
-            updateNativePowerStateLocked();
+            applyWakeLockFlagsOnReleaseLocked(wakeLock);
+            mDirty |= DIRTY_WAKE_LOCKS;
+            updatePowerStateLocked();
         }
     }
 
-    private void updateNativePowerStateLocked() {
-        if (!mHeadless) {
-            nativeSetPowerState(
-                    (mPowerState & SCREEN_ON_BIT) != 0,
-                    (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
+    private void handleWakeLockDeath(WakeLock wakeLock) {
+        synchronized (mLock) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "handleWakeLockDeath: lock=" + Objects.hashCode(wakeLock.mLock));
+            }
+
+            int index = mWakeLocks.indexOf(wakeLock);
+            if (index < 0) {
+                return;
+            }
+
+            mWakeLocks.remove(index);
+            notifyWakeLockReleasedLocked(wakeLock);
+
+            applyWakeLockFlagsOnReleaseLocked(wakeLock);
+            mDirty |= DIRTY_WAKE_LOCKS;
+            updatePowerStateLocked();
         }
     }
 
-    private int screenOffFinishedAnimatingLocked(int reason) {
-        // I don't think we need to check the current state here because all of these
-        // Power.setScreenState and sendNotificationLocked can both handle being
-        // called multiple times in the same state. -joeo
-        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, 0, 0);
-        int err = setScreenStateLocked(false);
-        if (err == 0) {
-            mScreenOffReason = reason;
-            sendNotificationLocked(false, reason);
+    private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
+        if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
+            userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER,
+                    PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
+                    wakeLock.mOwnerUid);
         }
-        return err;
     }
 
-    private boolean batteryIsLow() {
-        return (!mIsPowered &&
-                mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD);
-    }
+    @Override // Binder call
+    public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
+        if (lock == null) {
+            throw new IllegalArgumentException("lock must not be null");
+        }
 
-    private boolean shouldDeferScreenOnLocked() {
-        if (mPreparingForScreenOn) {
-            // Currently waiting for confirmation from the policy that it
-            // is okay to turn on the screen.  Don't allow the screen to go
-            // on until that is done.
-            if (DEBUG_SCREEN_ON) Slog.i(TAG,
-                    "updateLights: delaying screen on due to mPreparingForScreenOn");
-            return true;
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
+        if (ws != null && ws.size() != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.UPDATE_DEVICE_STATS, null);
         } else {
-            // If there is a screen-on command in the notification queue, we
-            // can't turn the screen on until it has been processed (and we
-            // have set mPreparingForScreenOn) or it has been dropped.
-            for (int i=0; i<mBroadcastQueue.length; i++) {
-                if (mBroadcastQueue[i] == 1) {
-                    if (DEBUG_SCREEN_ON) Slog.i(TAG,
-                            "updateLights: delaying screen on due to notification queue");
+            ws = null;
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            updateWakeLockWorkSourceInternal(lock, ws);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
+        synchronized (mLock) {
+            int index = findWakeLockIndexLocked(lock);
+            if (index < 0) {
+                throw new IllegalArgumentException("Wake lock not active");
+            }
+
+            WakeLock wakeLock = mWakeLocks.get(index);
+            if (!wakeLock.hasSameWorkSource(ws)) {
+                notifyWakeLockReleasedLocked(wakeLock);
+                wakeLock.updateWorkSource(ws);
+                notifyWakeLockAcquiredLocked(wakeLock);
+            }
+        }
+    }
+
+    private int findWakeLockIndexLocked(IBinder lock) {
+        final int count = mWakeLocks.size();
+        for (int i = 0; i < count; i++) {
+            if (mWakeLocks.get(i).mLock == lock) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
+        if (mSystemReady) {
+            mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
+        }
+    }
+
+    private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
+        if (mSystemReady) {
+            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
+        }
+    }
+
+    @Override // Binder call
+    public boolean isWakeLockLevelSupported(int level) {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            return isWakeLockLevelSupportedInternal(level);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private boolean isWakeLockLevelSupportedInternal(int level) {
+        synchronized (mLock) {
+            switch (level) {
+                case PowerManager.PARTIAL_WAKE_LOCK:
+                case PowerManager.SCREEN_DIM_WAKE_LOCK:
+                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+                case PowerManager.FULL_WAKE_LOCK:
                     return true;
-                }
+
+                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+                    return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
+
+                default:
+                    return false;
+            }
+        }
+    }
+
+    @Override // Binder call
+    public void userActivity(long eventTime, int event, int flags) {
+        if (eventTime > SystemClock.uptimeMillis()) {
+            throw new IllegalArgumentException("event time must not be in the future");
+        }
+
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            userActivityInternal(eventTime, event, flags, uid);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    // Called from native code.
+    private void userActivityFromNative(long eventTime, int event, int flags) {
+        userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID);
+    }
+
+    private void userActivityInternal(long eventTime, int event, int flags, int uid) {
+        synchronized (mLock) {
+            if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
+                updatePowerStateLocked();
+            }
+        }
+    }
+
+    private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
+        if (DEBUG_SPEW) {
+            Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
+                    + ", event=" + event + ", flags=0x" + Integer.toHexString(flags)
+                    + ", uid=" + uid);
+        }
+
+        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
+                || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) {
+            return false;
+        }
+
+        mNotifier.onUserActivity(event, uid);
+
+        if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
+            if (eventTime > mLastUserActivityTimeNoChangeLights
+                    && eventTime > mLastUserActivityTime) {
+                mLastUserActivityTimeNoChangeLights = eventTime;
+                mDirty |= DIRTY_USER_ACTIVITY;
+                return true;
+            }
+        } else {
+            if (eventTime > mLastUserActivityTime) {
+                mLastUserActivityTime = eventTime;
+                mDirty |= DIRTY_USER_ACTIVITY;
+                return true;
             }
         }
         return false;
     }
 
-    private void updateLightsLocked(int newState, int forceState) {
-        final int oldState = mPowerState;
+    @Override // Binder call
+    public void wakeUp(long eventTime) {
+        if (eventTime > SystemClock.uptimeMillis()) {
+            throw new IllegalArgumentException("event time must not be in the future");
+        }
 
-        // If the screen is not currently on, we will want to delay actually
-        // turning the lights on if we are still getting the UI put up.
-        if ((oldState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
-            // Don't turn screen on until we know we are really ready to.
-            // This is to avoid letting the screen go on before things like the
-            // lock screen have been displayed.
-            if ((mSkippedScreenOn = shouldDeferScreenOnLocked())) {
-                newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            wakeUpInternal(eventTime);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    // Called from native code.
+    private void wakeUpFromNative(long eventTime) {
+        wakeUpInternal(eventTime);
+    }
+
+    private void wakeUpInternal(long eventTime) {
+        synchronized (mLock) {
+            if (wakeUpNoUpdateLocked(eventTime)) {
+                updatePowerStateLocked();
             }
         }
+    }
 
-        if ((newState & SCREEN_ON_BIT) != 0) {
-            // Only turn on the buttons or keyboard if the screen is also on.
-            // We should never see the buttons on but not the screen.
-            newState = applyButtonState(newState);
-            newState = applyKeyboardState(newState);
+    private boolean wakeUpNoUpdateLocked(long eventTime) {
+        if (DEBUG_SPEW) {
+            Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime);
         }
-        final int realDifference = (newState ^ oldState);
-        final int difference = realDifference | forceState;
-        if (difference == 0) {
+
+        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
+                || !mBootCompleted || !mSystemReady) {
+            return false;
+        }
+
+        switch (mWakefulness) {
+            case WAKEFULNESS_ASLEEP:
+                Slog.i(TAG, "Waking up from sleep...");
+                mNotifier.onWakeUpStarted();
+                mSendWakeUpFinishedNotificationWhenReady = true;
+                mSendGoToSleepFinishedNotificationWhenReady = false;
+                break;
+            case WAKEFULNESS_DREAMING:
+                Slog.i(TAG, "Waking up from dream...");
+                break;
+            case WAKEFULNESS_NAPPING:
+                Slog.i(TAG, "Waking up from nap...");
+                break;
+        }
+
+        mLastWakeTime = eventTime;
+        mWakefulness = WAKEFULNESS_AWAKE;
+        mDirty |= DIRTY_WAKEFULNESS;
+
+        userActivityNoUpdateLocked(
+                eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+        return true;
+    }
+
+    @Override // Binder call
+    public void goToSleep(long eventTime, int reason) {
+        if (eventTime > SystemClock.uptimeMillis()) {
+            throw new IllegalArgumentException("event time must not be in the future");
+        }
+
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            goToSleepInternal(eventTime, reason);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    // Called from native code.
+    private void goToSleepFromNative(long eventTime, int reason) {
+        goToSleepInternal(eventTime, reason);
+    }
+
+    private void goToSleepInternal(long eventTime, int reason) {
+        synchronized (mLock) {
+            if (goToSleepNoUpdateLocked(eventTime, reason)) {
+                updatePowerStateLocked();
+            }
+        }
+    }
+
+    private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
+        if (DEBUG_SPEW) {
+            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
+        }
+
+        if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
+                || !mBootCompleted || !mSystemReady) {
+            return false;
+        }
+
+        switch (reason) {
+            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
+                Slog.i(TAG, "Going to sleep due to device administration policy...");
+                break;
+            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
+                Slog.i(TAG, "Going to sleep due to screen timeout...");
+                break;
+            default:
+                Slog.i(TAG, "Going to sleep by user request...");
+                reason = PowerManager.GO_TO_SLEEP_REASON_USER;
+                break;
+        }
+
+        mLastSleepTime = eventTime;
+        mDirty |= DIRTY_WAKEFULNESS;
+        mWakefulness = WAKEFULNESS_ASLEEP;
+        mNotifier.onGoToSleepStarted(reason);
+        mSendGoToSleepFinishedNotificationWhenReady = true;
+        mSendWakeUpFinishedNotificationWhenReady = false;
+
+        // Report the number of wake locks that will be cleared by going to sleep.
+        int numWakeLocksCleared = 0;
+        final int numWakeLocks = mWakeLocks.size();
+        for (int i = 0; i < numWakeLocks; i++) {
+            final WakeLock wakeLock = mWakeLocks.get(i);
+            switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+                case PowerManager.FULL_WAKE_LOCK:
+                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+                case PowerManager.SCREEN_DIM_WAKE_LOCK:
+                    numWakeLocksCleared += 1;
+                    break;
+            }
+        }
+        EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
+        return true;
+    }
+
+    /**
+     * Updates the global power state based on dirty bits recorded in mDirty.
+     *
+     * This is the main function that performs power state transitions.
+     * We centralize them here so that we can recompute the power state completely
+     * each time something important changes, and ensure that we do it the same
+     * way each time.  The point is to gather all of the transition logic here.
+     */
+    private void updatePowerStateLocked() {
+        if (!mSystemReady || mDirty == 0) {
             return;
         }
 
-        int offMask = 0;
-        int dimMask = 0;
-        int onMask = 0;
+        // Phase 0: Basic state updates.
+        updateIsPoweredLocked(mDirty);
+        updateStayOnLocked(mDirty);
 
-        int preferredBrightness = getPreferredBrightness();
+        // Phase 1: Update wakefulness.
+        // Loop because the wake lock and user activity computations are influenced
+        // by changes in wakefulness.
+        final long now = SystemClock.uptimeMillis();
+        int dirtyPhase2 = 0;
+        for (;;) {
+            int dirtyPhase1 = mDirty;
+            dirtyPhase2 |= dirtyPhase1;
+            mDirty = 0;
 
-        if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
-            if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
-                offMask |= KEYBOARD_BRIGHT_BIT;
-            } else {
-                onMask |= KEYBOARD_BRIGHT_BIT;
+            updateWakeLockSummaryLocked(dirtyPhase1);
+            updateUserActivitySummaryLocked(now, dirtyPhase1);
+            if (!updateWakefulnessLocked(dirtyPhase1)) {
+                break;
             }
         }
 
-        if ((difference & BUTTON_BRIGHT_BIT) != 0) {
-            if ((newState & BUTTON_BRIGHT_BIT) == 0) {
-                offMask |= BUTTON_BRIGHT_BIT;
-            } else {
-                onMask |= BUTTON_BRIGHT_BIT;
-            }
-        }
+        // Phase 2: Update dreams and display power state.
+        updateDreamLocked(dirtyPhase2);
+        updateDisplayPowerStateLocked(dirtyPhase2);
 
-        if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
-            int nominalCurrentValue = -1;
-            // If there was an actual difference in the light state, then
-            // figure out the "ideal" current value based on the previous
-            // state.  Otherwise, this is a change due to the brightness
-            // override, so we want to animate from whatever the current
-            // value is.
-            if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
-                switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
-                    case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
-                        nominalCurrentValue = preferredBrightness;
-                        break;
-                    case SCREEN_ON_BIT:
-                        nominalCurrentValue = mScreenBrightnessDim;
-                        break;
-                    case 0:
-                        nominalCurrentValue = PowerManager.BRIGHTNESS_OFF;
-                        break;
-                    case SCREEN_BRIGHT_BIT:
-                    default:
-                        // not possible
-                        nominalCurrentValue = (int)mScreenBrightnessAnimator.getCurrentBrightness();
-                        break;
-                }
-            }
-            int brightness = preferredBrightness;
-            int steps = ANIM_STEPS;
-            if ((newState & SCREEN_BRIGHT_BIT) == 0) {
-                // dim or turn off backlight, depending on if the screen is on
-                // the scale is because the brightness ramp isn't linear and this biases
-                // it so the later parts take longer.
-                final float scale = 1.5f;
-                float ratio = (((float)mScreenBrightnessDim)/preferredBrightness);
-                if (ratio > 1.0f) ratio = 1.0f;
-                if ((newState & SCREEN_ON_BIT) == 0) {
-                    if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
-                        // was bright
-                        steps = ANIM_STEPS;
-                    } else {
-                        // was dim
-                        steps = (int)(ANIM_STEPS*ratio*scale);
-                    }
-                    brightness = PowerManager.BRIGHTNESS_OFF;
-                } else {
-                    if ((oldState & SCREEN_ON_BIT) != 0) {
-                        // was bright
-                        steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
-                    } else {
-                        // was dim
-                        steps = (int)(ANIM_STEPS*ratio);
-                    }
-                    final int stayOnConditions = getStayOnConditionsLocked();
-                    if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
-                        // If the "stay on while plugged in" option is
-                        // turned on, then the screen will often not
-                        // automatically turn off while plugged in.  To
-                        // still have a sense of when it is inactive, we
-                        // will then count going dim as turning off.
-                        mScreenOffTime = SystemClock.elapsedRealtime();
-                    }
-                    brightness = mScreenBrightnessDim;
-                }
-            }
-            if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
-                steps = IMMEDIATE_ANIM_STEPS;
-            }
+        // Phase 3: Send notifications, if needed.
+        sendPendingNotificationsLocked();
 
-            long identity = Binder.clearCallingIdentity();
-            try {
-                mBatteryStats.noteScreenBrightness(brightness);
-            } catch (RemoteException e) {
-                // Nothing interesting to do.
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-            if (!mSkippedScreenOn) {
-                int dt = steps * NOMINAL_FRAME_TIME_MS;
-                mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, dt);
-                if (DEBUG_SCREEN_ON) {
-                    RuntimeException e = new RuntimeException("here");
-                    e.fillInStackTrace();
-                    Slog.i(TAG, "Setting screen brightness: " + brightness, e);
-                }
-            }
-        }
+        // Phase 4: Update suspend blocker.
+        // Because we might release the last suspend blocker here, we need to make sure
+        // we finished everything else first!
+        updateSuspendBlockerLocked();
+    }
 
-        if (DEBUG) {
-            Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)
-                    + " dimMask=0x" + Integer.toHexString(dimMask)
-                    + " onMask=0x" + Integer.toHexString(onMask)
-                    + " difference=0x" + Integer.toHexString(difference)
-                    + " realDifference=0x" + Integer.toHexString(realDifference)
-                    + " forceState=0x" + Integer.toHexString(forceState)
-                    );
-        }
-
-        if (offMask != 0) {
-            if (DEBUG) Slog.i(TAG, "Setting brightess off: " + offMask);
-            setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF);
-        }
-        if (dimMask != 0) {
-            int brightness = mScreenBrightnessDim;
-            if ((newState & BATTERY_LOW_BIT) != 0 &&
-                    brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
-                brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
+    private void sendPendingNotificationsLocked() {
+        if (mDisplayReady) {
+            if (mSendWakeUpFinishedNotificationWhenReady) {
+                mSendWakeUpFinishedNotificationWhenReady = false;
+                mNotifier.onWakeUpFinished();
             }
-            if (DEBUG) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);
-            setLightBrightness(dimMask, brightness);
-        }
-        if (onMask != 0) {
-            int brightness = getPreferredBrightness();
-            if ((newState & BATTERY_LOW_BIT) != 0 &&
-                    brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) {
-                brightness = PowerManager.BRIGHTNESS_LOW_BATTERY;
+            if (mSendGoToSleepFinishedNotificationWhenReady) {
+                mSendGoToSleepFinishedNotificationWhenReady = false;
+                mNotifier.onGoToSleepFinished();
             }
-            if (DEBUG) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);
-            setLightBrightness(onMask, brightness);
         }
     }
 
     /**
-     * Note: by design this class does not hold mLocks while calling native methods.
-     * Nor should it. Ever.
+     * Updates the value of mIsPowered.
+     * Sets DIRTY_IS_POWERED if a change occurred.
      */
-    class ScreenBrightnessAnimator extends HandlerThread {
-        static final int ANIMATE_LIGHTS = 10;
-        static final int ANIMATE_POWER_OFF = 11;
-        volatile int startValue;
-        volatile int endValue;
-        volatile int startSensorValue;
-        volatile int endSensorValue;
-        volatile int currentValue;
-        private int currentMask;
-        private int duration;
-        private long startTimeMillis;
-        private final String prefix;
+    private void updateIsPoweredLocked(int dirty) {
+        if ((dirty & DIRTY_BATTERY_STATE) != 0) {
+            boolean wasPowered = mIsPowered;
+            mIsPowered = mBatteryService.isPowered();
 
-        public ScreenBrightnessAnimator(String name, int priority) {
-            super(name, priority);
-            prefix = name;
+            if (wasPowered != mIsPowered) {
+                mDirty |= DIRTY_IS_POWERED;
+
+                // Treat plugging and unplugging the devices as a user activity.
+                // Users find it disconcerting when they plug or unplug the device
+                // and it shuts off right away.
+                // Some devices also wake the device when plugged or unplugged because
+                // they don't have a charging LED.
+                final long now = SystemClock.uptimeMillis();
+                if (mWakeUpWhenPluggedOrUnpluggedConfig) {
+                    wakeUpNoUpdateLocked(now);
+                }
+                userActivityNoUpdateLocked(
+                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+            }
+        }
+    }
+
+    /**
+     * Updates the value of mStayOn.
+     * Sets DIRTY_STAY_ON if a change occurred.
+     */
+    private void updateStayOnLocked(int dirty) {
+        if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
+            if (mStayOnWhilePluggedInSetting != 0
+                    && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
+                mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
+            } else {
+                mStayOn = false;
+            }
+        }
+    }
+
+    /**
+     * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
+     * Note that most wake-locks are ignored when the system is asleep.
+     *
+     * This function must have no other side-effects.
+     */
+    private void updateWakeLockSummaryLocked(int dirty) {
+        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
+            mWakeLockSummary = 0;
+
+            final int numWakeLocks = mWakeLocks.size();
+            for (int i = 0; i < numWakeLocks; i++) {
+                final WakeLock wakeLock = mWakeLocks.get(i);
+                switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+                    case PowerManager.PARTIAL_WAKE_LOCK:
+                        mWakeLockSummary |= WAKE_LOCK_CPU;
+                        break;
+                    case PowerManager.FULL_WAKE_LOCK:
+                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
+                            mWakeLockSummary |= WAKE_LOCK_CPU
+                                    | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
+                        }
+                        break;
+                    case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
+                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT;
+                        }
+                        break;
+                    case PowerManager.SCREEN_DIM_WAKE_LOCK:
+                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
+                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_DIM;
+                        }
+                        break;
+                    case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+                        if (mWakefulness != WAKEFULNESS_ASLEEP) {
+                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
+                        }
+                        break;
+                }
+            }
+
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
+                        + wakefulnessToString(mWakefulness)
+                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
+            }
+        }
+    }
+
+    /**
+     * Updates the value of mUserActivitySummary to summarize the user requested
+     * state of the system such as whether the screen should be bright or dim.
+     * Note that user activity is ignored when the system is asleep.
+     *
+     * This function must have no other side-effects.
+     */
+    private void updateUserActivitySummaryLocked(long now, int dirty) {
+        // Update the status of the user activity timeout timer.
+        if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
+            mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
+
+            long nextTimeout = 0;
+            if (mWakefulness != WAKEFULNESS_ASLEEP) {
+                final int screenOffTimeout = getScreenOffTimeoutLocked();
+                final int screenDimDuration = getScreenDimDurationLocked();
+
+                mUserActivitySummary = 0;
+                if (mLastUserActivityTime >= mLastWakeTime) {
+                    nextTimeout = mLastUserActivityTime
+                            + screenOffTimeout - screenDimDuration;
+                    if (now < nextTimeout) {
+                        mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
+                    } else {
+                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
+                        if (now < nextTimeout) {
+                            mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
+                        }
+                    }
+                }
+                if (mUserActivitySummary == 0
+                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
+                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
+                    if (now < nextTimeout
+                            && mDisplayPowerRequest.screenState
+                                    != DisplayPowerRequest.SCREEN_STATE_OFF) {
+                        mUserActivitySummary = mDisplayPowerRequest.screenState
+                                == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
+                                USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
+                    }
+                }
+                if (mUserActivitySummary != 0) {
+                    Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
+                    msg.setAsynchronous(true);
+                    mHandler.sendMessageAtTime(msg, nextTimeout);
+                }
+            } else {
+                mUserActivitySummary = 0;
+            }
+
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
+                        + wakefulnessToString(mWakefulness)
+                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
+            }
+        }
+    }
+
+    /**
+     * Called when a user activity timeout has occurred.
+     * Simply indicates that something about user activity has changed so that the new
+     * state can be recomputed when the power state is updated.
+     *
+     * This function must have no other side-effects besides setting the dirty
+     * bit and calling update power state.  Wakefulness transitions are handled elsewhere.
+     */
+    private void handleUserActivityTimeout() { // runs on handler thread
+        synchronized (mLock) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "handleUserActivityTimeout");
+            }
+
+            mDirty |= DIRTY_USER_ACTIVITY;
+            updatePowerStateLocked();
+        }
+    }
+
+    private int getScreenOffTimeoutLocked() {
+        int timeout = mScreenOffTimeoutSetting;
+        if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
+            timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
+        }
+        return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
+    }
+
+    private int getScreenDimDurationLocked() {
+        return SCREEN_DIM_DURATION;
+    }
+
+    /**
+     * Updates the wakefulness of the device.
+     *
+     * This is the function that decides whether the device should start napping
+     * based on the current wake locks and user activity state.  It may modify mDirty
+     * if the wakefulness changes.
+     *
+     * Returns true if the wakefulness changed and we need to restart power state calculation.
+     */
+    private boolean updateWakefulnessLocked(int dirty) {
+        boolean changed = false;
+        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
+                | DIRTY_WAKEFULNESS | DIRTY_STAY_ON)) != 0) {
+            if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
+                if (DEBUG_SPEW) {
+                    Slog.d(TAG, "updateWakefulnessLocked: Nap time...");
+                }
+                mWakefulness = WAKEFULNESS_NAPPING;
+                mDirty |= DIRTY_WAKEFULNESS;
+                changed = true;
+            }
+        }
+        return changed;
+    }
+
+    // Also used when exiting a dream to determine whether we should go back
+    // to being fully awake or else go to sleep for good.
+    private boolean isItBedTimeYetLocked() {
+        return mBootCompleted && !mStayOn
+                && (mWakeLockSummary
+                        & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) == 0
+                && (mUserActivitySummary
+                        & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) == 0;
+    }
+
+    /**
+     * Determines whether to post a message to the sandman to update the dream state.
+     */
+    private void updateDreamLocked(int dirty) {
+        if ((dirty & (DIRTY_WAKEFULNESS | DIRTY_SETTINGS
+                | DIRTY_IS_POWERED | DIRTY_STAY_ON)) != 0) {
+            scheduleSandmanLocked();
+        }
+    }
+
+    private void scheduleSandmanLocked() {
+        if (!mSandmanScheduled) {
+            mSandmanScheduled = true;
+            Message msg = mHandler.obtainMessage(MSG_SANDMAN);
+            msg.setAsynchronous(true);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    /**
+     * Called when the device enters or exits a napping or dreaming state.
+     *
+     * We do this asynchronously because we must call out of the power manager to start
+     * the dream and we don't want to hold our lock while doing so.  There is a risk that
+     * the device will wake or go to sleep in the meantime so we have to handle that case.
+     */
+    private void handleSandman() { // runs on handler thread
+        // Handle preconditions.
+        boolean startDreaming = false;
+        synchronized (mLock) {
+            mSandmanScheduled = false;
+
+            if (DEBUG_SPEW) {
+                Log.d(TAG, "handleSandman: canDream=" + canDreamLocked()
+                        + ", mWakefulness=" + wakefulnessToString(mWakefulness));
+            }
+
+            if (canDreamLocked() && mWakefulness == WAKEFULNESS_NAPPING) {
+                startDreaming = true;
+            }
+        }
+
+        // Get the dream manager, if needed.
+        if (startDreaming && mDreamManager == null) {
+            mDreamManager = IDreamManager.Stub.asInterface(
+                    ServiceManager.checkService("dreams"));
+            if (mDreamManager == null) {
+                Slog.w(TAG, "Unable to find IDreamManager.");
+            }
+        }
+
+        // Start dreaming if needed.
+        // We only control the dream on the handler thread, so we don't need to worry about
+        // concurrent attempts to start or stop the dream.
+        boolean isDreaming = false;
+        if (mDreamManager != null) {
+            try {
+                isDreaming = mDreamManager.isDreaming();
+                if (startDreaming && !isDreaming) {
+                    Slog.i(TAG, "Entering dreamland.");
+                    mDreamManager.dream();
+                    isDreaming = mDreamManager.isDreaming();
+                    if (!isDreaming) {
+                        Slog.i(TAG, "Could not enter dreamland.  Sleep will be dreamless.");
+                    }
+                }
+            } catch (RemoteException ex) {
+            }
+        }
+
+        // Update dream state.
+        // We might need to stop the dream again if the preconditions changed.
+        boolean continueDreaming = false;
+        synchronized (mLock) {
+            if (isDreaming && canDreamLocked()) {
+                if (mWakefulness == WAKEFULNESS_NAPPING) {
+                    mWakefulness = WAKEFULNESS_DREAMING;
+                    mDirty |= DIRTY_WAKEFULNESS;
+                    updatePowerStateLocked();
+                    continueDreaming = true;
+                } else if (mWakefulness == WAKEFULNESS_DREAMING) {
+                    continueDreaming = true;
+                }
+            }
+            if (!continueDreaming) {
+                handleDreamFinishedLocked();
+            }
+
+            // Allow the sandman to detect when the dream has ended.
+            // FIXME: The DreamManagerService should tell us explicitly.
+            if (mWakefulness == WAKEFULNESS_DREAMING
+                    || mWakefulness == WAKEFULNESS_NAPPING) {
+                if (!mSandmanScheduled) {
+                    mSandmanScheduled = true;
+                    Message msg = mHandler.obtainMessage(MSG_SANDMAN);
+                    msg.setAsynchronous(true);
+                    mHandler.sendMessageDelayed(msg, 1000);
+                }
+            }
+        }
+
+        // Stop dreaming if needed.
+        // It's possible that something else changed to make us need to start the dream again.
+        // If so, then the power manager will have posted another message to the handler
+        // to take care of it later.
+        if (mDreamManager != null) {
+            try {
+                if (!continueDreaming && isDreaming) {
+                    Slog.i(TAG, "Leaving dreamland.");
+                    mDreamManager.awaken();
+                }
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
+    /**
+     * Returns true if the device is allowed to dream in its current state,
+     * assuming there has been no recent user activity and no wake locks are held.
+     */
+    private boolean canDreamLocked() {
+        return mIsPowered && mDreamsSupportedConfig && mDreamsEnabledSetting;
+    }
+
+    /**
+     * Called when a dream is ending to figure out what to do next.
+     */
+    private void handleDreamFinishedLocked() {
+        if (mWakefulness == WAKEFULNESS_NAPPING
+                || mWakefulness == WAKEFULNESS_DREAMING) {
+            if (isItBedTimeYetLocked()) {
+                goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
+                        PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+                updatePowerStateLocked();
+            } else {
+                wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
+                updatePowerStateLocked();
+            }
+        }
+    }
+
+
+    /**
+     * Updates the display power state asynchronously.
+     * When the update is finished, mDisplayReady will be set to true.  The display
+     * controller posts a message to tell us when the actual display power state
+     * has been updated so we come back here to double-check and finish up.
+     *
+     * This function recalculates the display power state each time.
+     */
+    private void updateDisplayPowerStateLocked(int dirty) {
+        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
+                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
+                | DIRTY_SETTINGS)) != 0) {
+            int newScreenState = getDesiredScreenPowerState();
+            if (newScreenState != mDisplayPowerRequest.screenState) {
+                if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
+                        && mDisplayPowerRequest.screenState
+                                != DisplayPowerRequest.SCREEN_STATE_OFF) {
+                    mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime();
+                }
+
+                mDisplayPowerRequest.screenState = newScreenState;
+                nativeSetPowerState(
+                        newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF,
+                        newScreenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT);
+            }
+
+            int screenBrightness = mScreenBrightnessSettingDefault;
+            boolean autoBrightness = (mScreenBrightnessModeSetting ==
+                    Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+            if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
+                screenBrightness = mScreenBrightnessOverrideFromWindowManager;
+                autoBrightness = false;
+            } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
+                screenBrightness = mTemporaryScreenBrightnessSettingOverride;
+            } else if (isValidBrightness(mScreenBrightnessSetting)) {
+                screenBrightness =  mScreenBrightnessSetting;
+            }
+            if (autoBrightness) {
+                screenBrightness = mScreenBrightnessSettingDefault;
+            }
+            screenBrightness = Math.max(Math.min(screenBrightness,
+                    mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
+            mDisplayPowerRequest.screenBrightness = screenBrightness;
+            mDisplayPowerRequest.useAutoBrightness = autoBrightness;
+
+            mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
+
+            mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
+                    mRequestWaitForNegativeProximity);
+            mRequestWaitForNegativeProximity = false;
+
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateScreenStateLocked: displayReady=" + mDisplayReady
+                        + ", newScreenState=" + newScreenState
+                        + ", mWakefulness=" + mWakefulness
+                        + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+                        + ", mBootCompleted=" + mBootCompleted);
+            }
+        }
+    }
+
+    private static boolean isValidBrightness(int value) {
+        return value >= 0 && value <= 255;
+    }
+
+    private int getDesiredScreenPowerState() {
+        if (mWakefulness == WAKEFULNESS_ASLEEP) {
+            return DisplayPowerRequest.SCREEN_STATE_OFF;
+        }
+
+        if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
+                || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
+                || !mBootCompleted) {
+            return DisplayPowerRequest.SCREEN_STATE_BRIGHT;
+        }
+
+        return DisplayPowerRequest.SCREEN_STATE_DIM;
+    }
+
+    private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
+            new DisplayPowerController.Callbacks() {
+        @Override
+        public void onStateChanged() {
+            mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
+            updatePowerStateLocked();
         }
 
         @Override
-        protected void onLooperPrepared() {
-            mScreenBrightnessHandler = new Handler() {
-                public void handleMessage(Message msg) {
-                    int brightnessMode = (mAutoBrightessEnabled && !mInitialAnimation
-                            ? LightsService.BRIGHTNESS_MODE_SENSOR
-                            : LightsService.BRIGHTNESS_MODE_USER);
-                    if (msg.what == ANIMATE_LIGHTS) {
-                        final int mask = msg.arg1;
-                        int value = msg.arg2;
-                        long tStart = SystemClock.uptimeMillis();
-                        if ((mask & SCREEN_BRIGHT_BIT) != 0) {
-                            if (DEBUG_LIGHT_ANIMATION) Slog.v(TAG, "Set brightness: " + value);
-                            mLcdLight.setBrightness(value, brightnessMode);
-                        }
-                        long elapsed = SystemClock.uptimeMillis() - tStart;
-                        if ((mask & BUTTON_BRIGHT_BIT) != 0) {
-                            mButtonLight.setBrightness(value);
-                        }
-                        if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
-                            mKeyboardLight.setBrightness(value);
-                        }
+        public void onProximityNegative() {
+            userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
+                    PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+            updatePowerStateLocked();
+        }
+    };
 
-                        if (elapsed > 100) {
-                            Slog.e(TAG, "Excessive delay setting brightness: " + elapsed
-                                    + "ms, mask=" + mask);
-                        }
+    private boolean shouldUseProximitySensorLocked() {
+        return (mWakeLockSummary & WAKE_LOCK_PROXIMITY_SCREEN_OFF) != 0;
+    }
 
-                        // Throttle brightness updates to frame refresh rate
-                        int delay = elapsed < NOMINAL_FRAME_TIME_MS ? NOMINAL_FRAME_TIME_MS : 1;
-                        synchronized(this) {
-                            currentValue = value;
-                        }
-                        animateInternal(mask, false, delay);
-                    } else if (msg.what == ANIMATE_POWER_OFF) {
-                        int mode = msg.arg1;
-                        nativeStartSurfaceFlingerAnimation(mode);
-                    }
+    /**
+     * Updates the suspend blocker that keeps the CPU alive.
+     *
+     * This function must have no other side-effects.
+     */
+    private void updateSuspendBlockerLocked() {
+        boolean wantCpu = isCpuNeededLocked();
+        if (wantCpu != mHoldingWakeLockSuspendBlocker) {
+            mHoldingWakeLockSuspendBlocker = wantCpu;
+            if (wantCpu) {
+                if (DEBUG) {
+                    Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
                 }
-            };
-            synchronized (this) {
-                mInitComplete = true;
-                notifyAll();
-            }
-        }
-
-        private void animateInternal(int mask, boolean turningOff, int delay) {
-            synchronized (this) {
-                if (currentValue != endValue) {
-                    final long now = SystemClock.elapsedRealtime();
-                    final int elapsed = (int) (now - startTimeMillis);
-                    int newValue;
-                    if (elapsed < duration) {
-                        int delta = endValue - startValue;
-                        newValue = startValue + delta * elapsed / duration;
-                        newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue);
-                        newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue);
-                        // Optimization to delay next step until a change will occur.
-                        if (delay > 0 && newValue == currentValue) {
-                            final int timePerStep = duration / Math.abs(delta);
-                            delay = Math.min(duration - elapsed, timePerStep);
-                            newValue += delta < 0 ? -1 : 1;
-                        }
-                        // adjust the peak sensor value until we get to the target sensor value
-                        delta = endSensorValue - startSensorValue;
-                        mHighestLightSensorValue = startSensorValue + delta * elapsed / duration;
-                    } else {
-                        newValue = endValue;
-                        mHighestLightSensorValue = endSensorValue;
-                        if (endValue > 0) {
-                            mInitialAnimation = false;
-                        }
-                    }
-
-                    if (DEBUG_LIGHT_ANIMATION) {
-                        Slog.v(TAG, "Animating light: " + "start:" + startValue
-                                + ", end:" + endValue + ", elapsed:" + elapsed
-                                + ", duration:" + duration + ", current:" + currentValue
-                                + ", newValue:" + newValue
-                                + ", delay:" + delay
-                                + ", highestSensor:" + mHighestLightSensorValue);
-                    }
-
-                    if (turningOff && !mHeadless && !mAnimateScreenLights) {
-                        int mode = mScreenOffReason == OFF_BECAUSE_OF_PROX_SENSOR
-                                ? 0 : mAnimationSetting;
-                        if (DEBUG_LIGHT_ANIMATION) {
-                            Slog.v(TAG, "Doing power-off anim, mode=" + mode);
-                        }
-                        mScreenBrightnessHandler.obtainMessage(ANIMATE_POWER_OFF, mode, 0)
-                                .sendToTarget();
-                    }
-                    mScreenBrightnessHandler.removeMessages(
-                            ScreenBrightnessAnimator.ANIMATE_LIGHTS);
-                    Message msg = mScreenBrightnessHandler
-                            .obtainMessage(ANIMATE_LIGHTS, mask, newValue);
-                    mScreenBrightnessHandler.sendMessageDelayed(msg, delay);
-                }
-            }
-        }
-
-        public void dump(PrintWriter pw, String string) {
-            pw.println(string);
-            pw.println("  animating: " + "start:" + startValue + ", end:" + endValue
-                    + ", duration:" + duration + ", current:" + currentValue);
-            pw.println("  startSensorValue:" + startSensorValue
-                    + " endSensorValue:" + endSensorValue);
-            pw.println("  startTimeMillis:" + startTimeMillis
-                    + " now:" + SystemClock.elapsedRealtime());
-            pw.println("  currentMask:" + dumpPowerState(currentMask));
-        }
-
-        public void animateTo(int target, int mask, int animationDuration) {
-            animateTo(target, mHighestLightSensorValue, mask, animationDuration);
-        }
-
-        public void animateTo(int target, int sensorTarget, int mask, int animationDuration) {
-            synchronized(this) {
-                if ((mask & SCREEN_BRIGHT_BIT) == 0) {
-                    // We only animate keyboard and button when passed in with SCREEN_BRIGHT_BIT.
-                    if ((mask & BUTTON_BRIGHT_BIT) != 0) {
-                        mButtonLight.setBrightness(target);
-                    }
-                    if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {
-                        mKeyboardLight.setBrightness(target);
-                    }
-                    return;
-                }
-                if (isAnimating() && (mask ^ currentMask) != 0) {
-                    // current animation is unrelated to new animation, jump to final values
-                    cancelAnimation();
-                }
-                if (mInitialAnimation) {
-                    // jump to final value in one step the first time the brightness is set
-                    animationDuration = 0;
-                    if (target > 0) {
-                        mInitialAnimation = false;
-                    }
-                }
-                startValue = currentValue;
-                endValue = target;
-                startSensorValue = mHighestLightSensorValue;
-                endSensorValue = sensorTarget;
-                currentMask = mask;
-                duration = (int) (mWindowScaleAnimation * animationDuration);
-                startTimeMillis = SystemClock.elapsedRealtime();
-
-                if (DEBUG_LIGHT_ANIMATION) {
-                    Slog.v(TAG, "animateTo(target=" + target
-                            + ", sensor=" + sensorTarget
-                            + ", mask=" + mask
-                            + ", duration=" + animationDuration +")"
-                            + ", currentValue=" + currentValue
-                            + ", startTime=" + startTimeMillis);
-                }
-
-                if (target != currentValue) {
-                    final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
-                    final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF;
-                    if (turningOff && doScreenAnim) {
-                        // Cancel all pending animations since we're turning off
-                        mScreenBrightnessHandler.removeCallbacksAndMessages(null);
-                        screenOffFinishedAnimatingLocked(mScreenOffReason);
-                        duration = 200; // TODO: how long should this be?
-                    }
-                    if (doScreenAnim) {
-                        animateInternal(mask, turningOff, 0);
-                    }
-                    // TODO: Handle keyboard light animation when we have devices that support it
-                }
-            }
-        }
-
-        public int getCurrentBrightness() {
-            synchronized (this) {
-                return currentValue;
-            }
-        }
-
-        public boolean isAnimating() {
-            synchronized (this) {
-                return currentValue != endValue;
-            }
-        }
-
-        public void cancelAnimation() {
-            animateTo(endValue, currentMask, 0);
-        }
-    }
-
-    private void setLightBrightness(int mask, int value) {
-        mScreenBrightnessAnimator.animateTo(value, mask, 0);
-    }
-
-    private int getPreferredBrightness() {
-        int brightness = mScreenBrightnessSetting;
-        if (mScreenBrightnessOverride >= 0) {
-            brightness = mScreenBrightnessOverride;
-        } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
-                && mAutoBrightessEnabled) {
-            brightness = mLightSensorScreenBrightness;
-        }
-         // Don't let applications turn the screen all the way off
-        return Math.max(brightness, mScreenBrightnessDim);
-    }
-
-    private int applyButtonState(int state) {
-        int brightness = -1;
-        if ((state & BATTERY_LOW_BIT) != 0) {
-            // do not override brightness if the battery is low
-            return state;
-        }
-        if (mButtonBrightnessOverride >= 0) {
-            brightness = mButtonBrightnessOverride;
-        } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {
-            brightness = mLightSensorButtonBrightness;
-        }
-        if (brightness > 0) {
-            return state | BUTTON_BRIGHT_BIT;
-        } else if (brightness == 0) {
-            return state & ~BUTTON_BRIGHT_BIT;
-        } else {
-            return state;
-        }
-    }
-
-    private int applyKeyboardState(int state) {
-        int brightness = -1;
-        if ((state & BATTERY_LOW_BIT) != 0) {
-            // do not override brightness if the battery is low
-            return state;
-        }
-        if (!mKeyboardVisible) {
-            brightness = 0;
-        } else if (mButtonBrightnessOverride >= 0) {
-            brightness = mButtonBrightnessOverride;
-        } else if (mLightSensorKeyboardBrightness >= 0 && mUseSoftwareAutoBrightness) {
-            brightness =  mLightSensorKeyboardBrightness;
-        }
-        if (brightness > 0) {
-            return state | KEYBOARD_BRIGHT_BIT;
-        } else if (brightness == 0) {
-            return state & ~KEYBOARD_BRIGHT_BIT;
-        } else {
-            return state;
-        }
-    }
-
-    public boolean isScreenOn() {
-        synchronized (mLocks) {
-            return (mPowerState & SCREEN_ON_BIT) != 0;
-        }
-    }
-
-    boolean isScreenBright() {
-        synchronized (mLocks) {
-            return (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT;
-        }
-    }
-
-    private boolean isScreenTurningOffLocked() {
-        return (mScreenBrightnessAnimator.isAnimating()
-                && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF
-                && (mScreenBrightnessAnimator.currentMask & SCREEN_BRIGHT_BIT) != 0);
-    }
-
-    private boolean shouldLog(long time) {
-        synchronized (mLocks) {
-            if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
-                mWarningSpewThrottleTime = time;
-                mWarningSpewThrottleCount = 0;
-                return true;
-            } else if (mWarningSpewThrottleCount < 30) {
-                mWarningSpewThrottleCount++;
-                return true;
+                mWakeLockSuspendBlocker.acquire();
             } else {
-                return false;
-            }
-        }
-    }
-
-    private void forceUserActivityLocked() {
-        if (isScreenTurningOffLocked()) {
-            // cancel animation so userActivity will succeed
-            mScreenBrightnessAnimator.cancelAnimation();
-        }
-        boolean savedActivityAllowed = mUserActivityAllowed;
-        mUserActivityAllowed = true;
-        userActivity(SystemClock.uptimeMillis(), false);
-        mUserActivityAllowed = savedActivityAllowed;
-    }
-
-    public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        userActivity(time, -1, noChangeLights, PowerManager.USER_ACTIVITY_EVENT_OTHER, force, false);
-    }
-
-    public void userActivity(long time, boolean noChangeLights) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
-                != PackageManager.PERMISSION_GRANTED) {
-            if (shouldLog(time)) {
-                Slog.w(TAG, "Caller does not have DEVICE_POWER permission.  pid="
-                        + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
-            }
-            return;
-        }
-
-        userActivity(time, -1, noChangeLights, PowerManager.USER_ACTIVITY_EVENT_OTHER, false, false);
-    }
-
-    public void userActivity(long time, boolean noChangeLights, int eventType) {
-        userActivity(time, -1, noChangeLights, eventType, false, false);
-    }
-
-    public void userActivity(long time, boolean noChangeLights, int eventType, boolean force) {
-        userActivity(time, -1, noChangeLights, eventType, force, false);
-    }
-
-    /*
-     * Reset the user activity timeout to now + timeout.  This overrides whatever else is going
-     * on with user activity.  Don't use this function.
-     */
-    public void clearUserActivityTimeout(long now, long timeout) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        Slog.i(TAG, "clearUserActivity for " + timeout + "ms from now");
-        userActivity(now, timeout, false, PowerManager.USER_ACTIVITY_EVENT_OTHER, false, false);
-    }
-
-    private void userActivity(long time, long timeoutOverride, boolean noChangeLights,
-            int eventType, boolean force, boolean ignoreIfScreenOff) {
-
-        if (((mPokey & POKE_LOCK_IGNORE_TOUCH_EVENTS) != 0) && (eventType == PowerManager.USER_ACTIVITY_EVENT_TOUCH)) {
-            if (false) {
-                Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));
-            }
-            return;
-        }
-
-        synchronized (mLocks) {
-            if (DEBUG) {
-                Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time
-                        + " mUserActivityAllowed=" + mUserActivityAllowed
-                        + " mUserState=0x" + Integer.toHexString(mUserState)
-                        + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)
-                        + " mProximitySensorActive=" + mProximitySensorActive
-                        + " timeoutOverride=" + timeoutOverride
-                        + " force=" + force);
-            }
-            // ignore user activity if we are in the process of turning off the screen
-            if (isScreenTurningOffLocked()) {
-                Slog.d(TAG, "ignoring user activity while turning off screen");
-                return;
-            }
-            // ignore if the caller doesn't want this to allow the screen to turn
-            // on, and the screen is currently off.
-            if (ignoreIfScreenOff && (mPowerState & SCREEN_ON_BIT) == 0) {
-                return;
-            }
-            // Disable proximity sensor if if user presses power key while we are in the
-            // "waiting for proximity sensor to go negative" state.
-            if (mProximitySensorActive && mProximityWakeLockCount == 0) {
-                mProximitySensorActive = false;
-            }
-            if (mLastEventTime <= time || force) {
-                mLastEventTime = time;
-                if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
-                    // Only turn on button backlights if a button was pressed
-                    // and auto brightness is disabled
-                    if (eventType == PowerManager.USER_ACTIVITY_EVENT_BUTTON && !mUseSoftwareAutoBrightness) {
-                        mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
-                    } else {
-                        // don't clear button/keyboard backlights when the screen is touched.
-                        mUserState |= SCREEN_BRIGHT;
-                    }
-
-                    int uid = Binder.getCallingUid();
-                    long ident = Binder.clearCallingIdentity();
-                    try {
-                        mBatteryStats.noteUserActivity(uid, eventType);
-                    } catch (RemoteException e) {
-                        // Ignore
-                    } finally {
-                        Binder.restoreCallingIdentity(ident);
-                    }
-
-                    mWakeLockState = mLocks.reactivateScreenLocksLocked();
-                    setPowerState(mUserState | mWakeLockState, noChangeLights,
-                            WindowManagerPolicy.OFF_BECAUSE_OF_USER);
-                    setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);
+                if (DEBUG) {
+                    Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
                 }
+                mWakeLockSuspendBlocker.release();
             }
         }
-
-        if (mPolicy != null) {
-            mPolicy.userActivity();
-        }
     }
 
-    private int getAutoBrightnessValue(int sensorValue, int[] values) {
+    private boolean isCpuNeededLocked() {
+        return !mBootCompleted
+                || mWakeLockSummary != 0
+                || mUserActivitySummary != 0
+                || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
+                || !mDisplayReady;
+    }
+
+    @Override // Binder call
+    public boolean isScreenOn() {
+        final long ident = Binder.clearCallingIdentity();
         try {
-            int i;
-            for (i = 0; i < mAutoBrightnessLevels.length; i++) {
-                if (sensorValue < mAutoBrightnessLevels[i]) {
-                    break;
-                }
-            }
-            // This is the range of brightness values that we can use.
-            final int minval = values[0];
-            final int maxval = values[mAutoBrightnessLevels.length];
-            // This is the range we will be scaling.  We put some padding
-            // at the low and high end to give the adjustment a little better
-            // impact on the actual observed value.
-            final int range = (maxval-minval) + LIGHT_SENSOR_RANGE_EXPANSION;
-            // This is the desired brightness value from 0.0 to 1.0.
-            float valf = ((values[i]-minval+(LIGHT_SENSOR_RANGE_EXPANSION/2))/(float)range);
-            // Apply a scaling to the value based on the adjustment.
-            if (mLightSensorAdjustSetting > 0 && mLightSensorAdjustSetting <= 1) {
-                float adj = (float)Math.sqrt(1.0f-mLightSensorAdjustSetting);
-                if (adj <= .00001) {
-                    valf = 1;
-                } else {
-                    valf /= adj;
-                }
-            } else if (mLightSensorAdjustSetting < 0 && mLightSensorAdjustSetting >= -1) {
-                float adj = (float)Math.sqrt(1.0f+mLightSensorAdjustSetting);
-                valf *= adj;
-            }
-            // Apply an additional offset to the value based on the adjustment.
-            valf += mLightSensorAdjustSetting/LIGHT_SENSOR_OFFSET_SCALE;
-            // Convert the 0.0-1.0 value back to a brightness integer.
-            int val = (int)((valf*range)+minval) - (LIGHT_SENSOR_RANGE_EXPANSION/2);
-            if (val < minval) val = minval;
-            else if (val > maxval) val = maxval;
-            return val;
-        } catch (Exception e) {
-            // guard against null pointer or index out of bounds errors
-            Slog.e(TAG, "Values array must be non-empty and must be one element longer than "
-                    + "the auto-brightness levels array.  Check config.xml.", e);
-            return 255;
+            return isScreenOnInternal();
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private Runnable mProximityTask = new Runnable() {
-        public void run() {
-            synchronized (mLocks) {
-                if (mProximityPendingValue != -1) {
-                    proximityChangedLocked(mProximityPendingValue == 1);
-                    mProximityPendingValue = -1;
-                }
-                if (mProximityPartialLock.isHeld()) {
-                    mProximityPartialLock.release();
-                }
-            }
-        }
-    };
-
-    private Runnable mAutoBrightnessTask = new Runnable() {
-        public void run() {
-            synchronized (mLocks) {
-                if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
-                    int value = (int)mLightSensorPendingValue;
-                    mLightSensorPendingDecrease = false;
-                    mLightSensorPendingIncrease = false;
-                    lightSensorChangedLocked(value, false);
-                }
-            }
-        }
-    };
-
-    /** used to prevent lightsensor changes while turning on. */
-    private boolean mInitialAnimation = true;
-
-    private void dockStateChanged(int state) {
-        synchronized (mLocks) {
-            mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
-            if (mIsDocked) {
-                // allow brightness to decrease when docked
-                mHighestLightSensorValue = -1;
-            }
-            if ((mPowerState & SCREEN_ON_BIT) != 0) {
-                // force lights recalculation
-                int value = (int)mLightSensorValue;
-                mLightSensorValue = -1;
-                lightSensorChangedLocked(value, false);
-            }
+    private boolean isScreenOnInternal() {
+        synchronized (mLock) {
+            return !mSystemReady
+                    || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
         }
     }
 
-    private void lightSensorChangedLocked(int value, boolean immediate) {
-        if (DEBUG_LIGHT_SENSOR) {
-            Slog.d(TAG, "lightSensorChangedLocked value=" + value + " immediate=" + immediate);
-        }
-
-        // Don't do anything if the screen is off.
-        if ((mPowerState & SCREEN_ON_BIT) == 0) {
-            if (DEBUG_LIGHT_SENSOR) {
-                Slog.d(TAG, "dropping lightSensorChangedLocked because screen is off");
-            }
-            return;
-        }
-
-        if (mLightSensorValue != value) {
-            mLightSensorValue = value;
-            if ((mPowerState & BATTERY_LOW_BIT) == 0) {
-                // use maximum light sensor value seen since screen went on for LCD to avoid flicker
-                // we only do this if we are undocked, since lighting should be stable when
-                // stationary in a dock.
-                int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
-                int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
-                int keyboardValue;
-                if (mKeyboardVisible) {
-                    keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
-                } else {
-                    keyboardValue = 0;
-                }
-                mLightSensorScreenBrightness = lcdValue;
-                mLightSensorButtonBrightness = buttonValue;
-                mLightSensorKeyboardBrightness = keyboardValue;
-
-                if (DEBUG_LIGHT_SENSOR) {
-                    Slog.d(TAG, "lcdValue " + lcdValue);
-                    Slog.d(TAG, "buttonValue " + buttonValue);
-                    Slog.d(TAG, "keyboardValue " + keyboardValue);
-                }
-
-                if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
-                    if (!mSkippedScreenOn && !mInitialAnimation) {
-                        final int steps;
-                        if (immediate) {
-                            steps = IMMEDIATE_ANIM_STEPS;
-                        } else {
-                            synchronized (mScreenBrightnessAnimator) {
-                                if (mScreenBrightnessAnimator.currentValue <= lcdValue) {
-                                    steps = AUTOBRIGHTNESS_ANIM_STEPS;
-                                } else {
-                                    steps = AUTODIMNESS_ANIM_STEPS;
-                                }
-                            }
-                        }
-                        mScreenBrightnessAnimator.animateTo(lcdValue, value,
-                                SCREEN_BRIGHT_BIT, steps * NOMINAL_FRAME_TIME_MS);
-                    }
-                }
-                if (mButtonBrightnessOverride < 0) {
-                    mButtonLight.setBrightness(buttonValue);
-                }
-                if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
-                    mKeyboardLight.setBrightness(keyboardValue);
-                }
-            }
-        }
+    private void handleBatteryStateChangedLocked() {
+        mDirty |= DIRTY_BATTERY_STATE;
+        updatePowerStateLocked();
     }
 
-    /**
-     * The user requested that we go to sleep (probably with the power button).
-     * This overrides all wake locks that are held.
-     */
-    public void goToSleep(long time)
-    {
-        goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
+    private void handleBootCompletedLocked() {
+        final long now = SystemClock.uptimeMillis();
+        mBootCompleted = true;
+        mDirty |= DIRTY_BOOT_COMPLETED;
+        userActivityNoUpdateLocked(
+                now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+        updatePowerStateLocked();
     }
 
-    /**
-     * The user requested that we go to sleep (probably with the power button).
-     * This overrides all wake locks that are held.
-     */
-    public void goToSleepWithReason(long time, int reason)
-    {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        synchronized (mLocks) {
-            goToSleepLocked(time, reason);
-        }
+    private void handleDockStateChangedLocked(int dockState) {
+        // TODO
     }
 
     /**
      * Reboot the device immediately, passing 'reason' (may be null)
      * to the underlying __reboot system call.  Should not return.
      */
-    public void reboot(String reason)
-    {
+    @Override // Binder call
+    public void reboot(String reason) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
 
-        if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            rebootInternal(reason);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void rebootInternal(final String reason) {
+        if (mHandler == null || !mSystemReady) {
             throw new IllegalStateException("Too early to call reboot()");
         }
 
-        final String finalReason = reason;
         Runnable runnable = new Runnable() {
             public void run() {
                 synchronized (this) {
-                    ShutdownThread.reboot(mContext, finalReason, false);
+                    ShutdownThread.reboot(mContext, reason, false);
                 }
-
             }
         };
+
         // ShutdownThread must run on a looper capable of displaying the UI.
-        mHandler.post(runnable);
+        Message msg = Message.obtain(mHandler, runnable);
+        msg.setAsynchronous(true);
+        mHandler.sendMessage(msg);
 
         // PowerManager.reboot() is documented not to return so just wait for the inevitable.
         synchronized (runnable) {
@@ -2798,11 +1463,23 @@
      * Crash the runtime (causing a complete restart of the Android framework).
      * Requires REBOOT permission.  Mostly for testing.  Should not return.
      */
-    public void crash(final String message)
-    {
+    @Override // Binder call
+    public void crash(String message) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            crashInternal(message);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void crashInternal(final String message) {
         Thread t = new Thread("PowerManagerService.crash()") {
-            public void run() { throw new RuntimeException(message); }
+            public void run() {
+                throw new RuntimeException(message);
+            }
         };
         try {
             t.start();
@@ -2812,581 +1489,554 @@
         }
     }
 
-    private void goToSleepLocked(long time, int reason) {
-        if (DEBUG) {
-            Exception ex = new Exception();
-            ex.fillInStackTrace();
-            Slog.d(TAG, "goToSleep mLastEventTime=" + mLastEventTime + " time=" + time
-                    + " reason=" + reason, ex);
-        }
-
-        if (mLastEventTime <= time) {
-            mLastEventTime = time;
-            // cancel all of the wake locks
-            mWakeLockState = SCREEN_OFF;
-            int N = mLocks.size();
-            int numCleared = 0;
-            boolean proxLock = false;
-            for (int i=0; i<N; i++) {
-                WakeLock wl = mLocks.get(i);
-                if (isScreenLock(wl.flags)) {
-                    if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
-                            && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
-                        proxLock = true;
-                    } else {
-                        mLocks.get(i).activated = false;
-                        numCleared++;
-                    }
-                }
-            }
-            if (!proxLock) {
-                mProxIgnoredBecauseScreenTurnedOff = true;
-                if (DEBUG_PROXIMITY_SENSOR) {
-                    Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");
-                }
-            }
-            EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);
-            mStillNeedSleepNotification = true;
-            mUserState = SCREEN_OFF;
-            setPowerState(SCREEN_OFF, false, reason);
-            cancelTimerLocked();
-        }
+    @Override // Binder call
+    public void clearUserActivityTimeout(long now, long timeout) {
+        // TODO Auto-generated method stub
+        // Only used by phone app, delete this
     }
 
-    public long timeSinceScreenOn() {
-        synchronized (mLocks) {
-            if ((mPowerState & SCREEN_ON_BIT) != 0) {
-                return 0;
-            }
-            return SystemClock.elapsedRealtime() - mScreenOffTime;
-        }
-    }
-
-    public void setKeyboardVisibility(boolean visible) {
-        synchronized (mLocks) {
-            if (DEBUG) {
-                Slog.d(TAG, "setKeyboardVisibility: " + visible);
-            }
-            if (mKeyboardVisible != visible) {
-                mKeyboardVisible = visible;
-                // don't signal user activity if the screen is off; other code
-                // will take care of turning on due to a true change to the lid
-                // switch and synchronized with the lock screen.
-                if ((mPowerState & SCREEN_ON_BIT) != 0) {
-                    if (mUseSoftwareAutoBrightness) {
-                        // force recompute of backlight values
-                        if (mLightSensorValue >= 0) {
-                            int value = (int)mLightSensorValue;
-                            mLightSensorValue = -1;
-                            lightSensorChangedLocked(value, false);
-                        }
-                    }
-                    userActivity(SystemClock.uptimeMillis(), false, PowerManager.USER_ACTIVITY_EVENT_BUTTON, true);
-                }
-            }
-        }
+    @Override // Binder call
+    public void setPokeLock(int pokey, IBinder lock, String tag) {
+        // TODO Auto-generated method stub
+        // Only used by phone app, delete this
     }
 
     /**
-     * When the keyguard is up, it manages the power state, and userActivity doesn't do anything.
-     * When disabling user activity we also reset user power state so the keyguard can reset its
-     * short screen timeout when keyguard is unhidden.
+     * Set the setting that determines whether the device stays on when plugged in.
+     * The argument is a bit string, with each bit specifying a power source that,
+     * when the device is connected to that source, causes the device to stay on.
+     * See {@link android.os.BatteryManager} for the list of power sources that
+     * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
+     * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB}
+     *
+     * Used by "adb shell svc power stayon ..."
+     *
+     * @param val an {@code int} containing the bits that specify which power sources
+     * should cause the device to stay on.
      */
-    public void enableUserActivity(boolean enabled) {
-        if (DEBUG) {
-            Slog.d(TAG, "enableUserActivity " + enabled);
-        }
-        synchronized (mLocks) {
-            mUserActivityAllowed = enabled;
-            if (!enabled) {
-                // cancel timeout and clear mUserState so the keyguard can set a short timeout
-                setTimeoutLocked(SystemClock.uptimeMillis(), 0);
-            }
+    @Override // Binder call
+    public void setStayOnSetting(int val) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setStayOnSettingInternal(val);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private void setScreenBrightnessMode(int mode) {
-        synchronized (mLocks) {
-            boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-            if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
-                mAutoBrightessEnabled = enabled;
-                // This will get us a new value
-                enableLightSensorLocked(mAutoBrightessEnabled && isScreenOn());
-            }
-        }
-    }
-
-    /** Sets the screen off timeouts:
-     *      mKeylightDelay
-     *      mDimDelay
-     *      mScreenOffDelay
-     * */
-    private void setScreenOffTimeoutsLocked() {
-        if ((mPokey & POKE_LOCK_SHORT_TIMEOUT) != 0) {
-            mKeylightDelay = mShortKeylightDelay;  // Configurable via secure settings
-            mDimDelay = -1;
-            mScreenOffDelay = 0;
-        } else if ((mPokey & POKE_LOCK_MEDIUM_TIMEOUT) != 0) {
-            mKeylightDelay = MEDIUM_KEYLIGHT_DELAY;
-            mDimDelay = -1;
-            mScreenOffDelay = 0;
-        } else {
-            int totalDelay = mScreenOffTimeoutSetting;
-            if (totalDelay > mMaximumScreenOffTimeout) {
-                totalDelay = mMaximumScreenOffTimeout;
-            }
-            mKeylightDelay = LONG_KEYLIGHT_DELAY;
-            if (totalDelay < 0) {
-                // negative number means stay on as long as possible.
-                mScreenOffDelay = mMaximumScreenOffTimeout;
-            } else if (mKeylightDelay < totalDelay) {
-                // subtract the time that the keylight delay. This will give us the
-                // remainder of the time that we need to sleep to get the accurate
-                // screen off timeout.
-                mScreenOffDelay = totalDelay - mKeylightDelay;
-            } else {
-                mScreenOffDelay = 0;
-            }
-            if (mDimScreen && totalDelay >= (LONG_KEYLIGHT_DELAY + LONG_DIM_TIME)) {
-                mDimDelay = mScreenOffDelay - LONG_DIM_TIME;
-                mScreenOffDelay = LONG_DIM_TIME;
-            } else {
-                mDimDelay = -1;
-            }
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "setScreenOffTimeouts mKeylightDelay=" + mKeylightDelay
-                    + " mDimDelay=" + mDimDelay + " mScreenOffDelay=" + mScreenOffDelay
-                    + " mDimScreen=" + mDimScreen);
-        }
+    private void setStayOnSettingInternal(int val) {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.System.STAY_ON_WHILE_PLUGGED_IN, val);
     }
 
     /**
-     * Refreshes cached secure settings.  Called once on startup, and
-     * on subsequent changes to secure settings.
+     * Used by device administration to set the maximum screen off timeout.
+     *
+     * This method must only be called by the device administration policy manager.
      */
-    private void updateSettingsValues() {
-        mShortKeylightDelay = Settings.Secure.getInt(
-                mContext.getContentResolver(),
-                Settings.Secure.SHORT_KEYLIGHT_DELAY_MS,
-                SHORT_KEYLIGHT_DELAY_DEFAULT);
-        // Slog.i(TAG, "updateSettingsValues(): mShortKeylightDelay now " + mShortKeylightDelay);
-    }
-
-    private class LockList extends ArrayList<WakeLock>
-    {
-        void addLock(WakeLock wl)
-        {
-            int index = getIndex(wl.binder);
-            if (index < 0) {
-                this.add(wl);
-            }
-        }
-
-        WakeLock removeLock(IBinder binder)
-        {
-            int index = getIndex(binder);
-            if (index >= 0) {
-                return this.remove(index);
-            } else {
-                return null;
-            }
-        }
-
-        int getIndex(IBinder binder)
-        {
-            int N = this.size();
-            for (int i=0; i<N; i++) {
-                if (this.get(i).binder == binder) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        int gatherState()
-        {
-            int result = 0;
-            int N = this.size();
-            for (int i=0; i<N; i++) {
-                WakeLock wl = this.get(i);
-                if (wl.activated) {
-                    if (isScreenLock(wl.flags)) {
-                        result |= wl.minState;
-                    }
-                }
-            }
-            return result;
-        }
-
-        int reactivateScreenLocksLocked()
-        {
-            int result = 0;
-            int N = this.size();
-            for (int i=0; i<N; i++) {
-                WakeLock wl = this.get(i);
-                if (isScreenLock(wl.flags)) {
-                    wl.activated = true;
-                    result |= wl.minState;
-                }
-            }
-            if (DEBUG_PROXIMITY_SENSOR) {
-                Slog.d(TAG, "reactivateScreenLocksLocked mProxIgnoredBecauseScreenTurnedOff="
-                        + mProxIgnoredBecauseScreenTurnedOff);
-            }
-            mProxIgnoredBecauseScreenTurnedOff = false;
-            return result;
+    @Override // Binder call
+    public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
-    public void setPolicy(WindowManagerPolicy p) {
-        synchronized (mLocks) {
-            mPolicy = p;
-            mLocks.notifyAll();
+    private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {
+        synchronized (mLock) {
+            mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs;
+            mDirty |= DIRTY_SETTINGS;
+            updatePowerStateLocked();
         }
     }
 
-    WindowManagerPolicy getPolicyLocked() {
-        while (mPolicy == null || !mDoneBooting) {
-            try {
-                mLocks.wait();
-            } catch (InterruptedException e) {
-                // Ignore
-            }
-        }
-        return mPolicy;
+    private boolean isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() {
+        return mMaximumScreenOffTimeoutFromDeviceAdmin >= 0
+                && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;
     }
 
-    public void systemReady() {
-        mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
-        mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-        // don't bother with the light sensor if auto brightness is handled in hardware
-        if (mUseSoftwareAutoBrightness) {
-            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-        }
-
-        // wait until sensors are enabled before turning on screen.
-        // some devices will not activate the light sensor properly on boot
-        // unless we do this.
-        if (mUseSoftwareAutoBrightness) {
-            // turn the screen on
-            setPowerState(SCREEN_BRIGHT);
-        } else {
-            // turn everything on
-            setPowerState(ALL_BRIGHT);
-        }
-
-        synchronized (mLocks) {
-            Slog.d(TAG, "system ready!");
-            mDoneBooting = true;
-
-            enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);
-
-            long identity = Binder.clearCallingIdentity();
-            try {
-                mBatteryStats.noteScreenBrightness(getPreferredBrightness());
-                mBatteryStats.noteScreenOn();
-            } catch (RemoteException e) {
-                // Nothing interesting to do.
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
+    @Override // Binder call
+    public void preventScreenOn(boolean prevent) {
+        // TODO Auto-generated method stub
+        // Only used by phone app, delete this
     }
 
-    void bootCompleted() {
-        Slog.d(TAG, "bootCompleted");
-        synchronized (mLocks) {
-            mBootCompleted = true;
-            userActivity(SystemClock.uptimeMillis(), false, PowerManager.USER_ACTIVITY_EVENT_BUTTON, true);
-            updateWakeLockLocked();
-            mLocks.notifyAll();
-        }
-    }
-
-    // for watchdog
-    public void monitor() {
-        synchronized (mLocks) { }
-    }
-
-    public int getSupportedWakeLockFlags() {
-        int result = PowerManager.PARTIAL_WAKE_LOCK
-                   | PowerManager.FULL_WAKE_LOCK
-                   | PowerManager.SCREEN_DIM_WAKE_LOCK;
-
-        if (mProximitySensor != null) {
-            result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
-        }
-
-        return result;
-    }
-
-    public void setBacklightBrightness(int brightness) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        // Don't let applications turn the screen all the way off
-        synchronized (mLocks) {
-            brightness = Math.max(brightness, mScreenBrightnessDim);
-            mLcdLight.setBrightness(brightness);
-            mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
-            mButtonLight.setBrightness(brightness);
-            long identity = Binder.clearCallingIdentity();
-            try {
-                mBatteryStats.noteScreenBrightness(brightness);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-            mScreenBrightnessAnimator.animateTo(brightness, SCREEN_BRIGHT_BIT, 0);
-        }
-    }
-
-    public void setAutoBrightnessAdjustment(float adj) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        synchronized (mLocks) {
-            mLightSensorAdjustSetting = adj;
-            if (mSensorManager != null && mLightSensorEnabled) {
-                // clear calling identity so sensor manager battery stats are accurate
-                long identity = Binder.clearCallingIdentity();
-                try {
-                    // force recompute of backlight values
-                    if (mLightSensorValue >= 0) {
-                        int value = (int)mLightSensorValue;
-                        mLightSensorValue = -1;
-                        handleLightSensorValue(value, true);
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-        }
-    }
-
+    /**
+     * Used by the phone application to make the attention LED flash when ringing.
+     */
+    @Override // Binder call
     public void setAttentionLight(boolean on, int color) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-        mAttentionLight.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setAttentionLightInternal(on, color);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
-    private void enableProximityLockLocked() {
-        if (DEBUG_PROXIMITY_SENSOR) {
-            Slog.d(TAG, "enableProximityLockLocked");
+    private void setAttentionLightInternal(boolean on, int color) {
+        LightsService.Light light;
+        synchronized (mLock) {
+            if (!mSystemReady) {
+                return;
+            }
+            light = mAttentionLight;
         }
-        if (!mProximitySensorEnabled) {
-            // clear calling identity so sensor manager battery stats are accurate
-            long identity = Binder.clearCallingIdentity();
-            try {
-                mSensorManager.registerListener(mProximityListener, mProximitySensor,
-                        SensorManager.SENSOR_DELAY_NORMAL);
-                mProximitySensorEnabled = true;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
+
+        // Control light outside of lock.
+        light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
+    }
+
+    /**
+     * Used by the Watchdog.
+     */
+    public long timeSinceScreenWasLastOn() {
+        synchronized (mLock) {
+            if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+                return 0;
+            }
+            return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime;
+        }
+    }
+
+    /**
+     * Used by the window manager to override the screen brightness based on the
+     * current foreground activity.
+     *
+     * This method must only be called by the window manager.
+     *
+     * @param brightness The overridden brightness, or -1 to disable the override.
+     */
+    public void setScreenBrightnessOverrideFromWindowManager(int brightness) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setScreenBrightnessOverrideFromWindowManagerInternal(brightness);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
+        synchronized (mLock) {
+            if (mScreenBrightnessOverrideFromWindowManager != brightness) {
+                mScreenBrightnessOverrideFromWindowManager = brightness;
+                mDirty |= DIRTY_SETTINGS;
+                updatePowerStateLocked();
             }
         }
     }
 
-    private void disableProximityLockLocked() {
-        if (DEBUG_PROXIMITY_SENSOR) {
-            Slog.d(TAG, "disableProximityLockLocked");
+    /**
+     * Used by the window manager to override the button brightness based on the
+     * current foreground activity.
+     *
+     * This method must only be called by the window manager.
+     *
+     * @param brightness The overridden brightness, or -1 to disable the override.
+     */
+    public void setButtonBrightnessOverrideFromWindowManager(int brightness) {
+        // Do nothing.
+        // Button lights are not currently supported in the new implementation.
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+    }
+
+    /**
+     * Used by the settings application and brightness control widgets to
+     * temporarily override the current screen brightness setting so that the
+     * user can observe the effect of an intended settings change without applying
+     * it immediately.
+     *
+     * The override will be canceled when the setting value is next updated.
+     *
+     * @param brightness The overridden brightness.
+     *
+     * @see Settings.System#SCREEN_BRIGHTNESS
+     */
+    @Override // Binder call
+    public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
-        if (mProximitySensorEnabled) {
-            // clear calling identity so sensor manager battery stats are accurate
-            long identity = Binder.clearCallingIdentity();
-            try {
-                mSensorManager.unregisterListener(mProximityListener);
-                mHandler.removeCallbacks(mProximityTask);
-                if (mProximityPartialLock.isHeld()) {
-                    mProximityPartialLock.release();
-                }
-                mProximitySensorEnabled = false;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-            if (mProximitySensorActive) {
-                mProximitySensorActive = false;
-                if (DEBUG_PROXIMITY_SENSOR) {
-                    Slog.d(TAG, "disableProximityLockLocked mProxIgnoredBecauseScreenTurnedOff="
-                            + mProxIgnoredBecauseScreenTurnedOff);
-                }
-                if (!mProxIgnoredBecauseScreenTurnedOff) {
-                    forceUserActivityLocked();
-                }
+    }
+
+    private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
+        synchronized (mLock) {
+            if (mTemporaryScreenBrightnessSettingOverride != brightness) {
+                mTemporaryScreenBrightnessSettingOverride = brightness;
+                mDirty |= DIRTY_SETTINGS;
+                updatePowerStateLocked();
             }
         }
     }
 
-    private void proximityChangedLocked(boolean active) {
-        if (DEBUG_PROXIMITY_SENSOR) {
-            Slog.d(TAG, "proximityChangedLocked, active: " + active);
+    /**
+     * Used by the settings application and brightness control widgets to
+     * temporarily override the current screen auto-brightness adjustment setting so that the
+     * user can observe the effect of an intended settings change without applying
+     * it immediately.
+     *
+     * The override will be canceled when the setting value is next updated.
+     *
+     * @param adj The overridden brightness, or -1 to disable the override.
+     *
+     * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
+     */
+    @Override // Binder call
+    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {
+        // Not implemented.
+        // The SCREEN_AUTO_BRIGHTNESS_ADJ setting is not currently supported.
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+    }
+
+    /**
+     * Low-level function turn the device off immediately, without trying
+     * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
+     */
+    public static void lowLevelShutdown() {
+        nativeShutdown();
+    }
+
+    /**
+     * Low-level function to reboot the device.
+     *
+     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
+     * @throws IOException if reboot fails for some reason (eg, lack of
+     *         permission)
+     */
+    public static void lowLevelReboot(String reason) throws IOException {
+        nativeReboot(reason);
+    }
+
+    @Override // Watchdog.Monitor implementation
+    public void monitor() {
+        // Grab and release lock for watchdog monitor to detect deadlocks.
+        synchronized (mLock) {
         }
-        if (!mProximitySensorEnabled) {
-            Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
+    }
+
+    @Override // Binder call
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump PowerManager from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
             return;
         }
-        if (active) {
-            if (DEBUG_PROXIMITY_SENSOR) {
-                Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
-                        + mProxIgnoredBecauseScreenTurnedOff);
-            }
-            if (!mProxIgnoredBecauseScreenTurnedOff) {
-                goToSleepLocked(SystemClock.uptimeMillis(),
-                        WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
-            }
-            mProximitySensorActive = true;
-        } else {
-            // proximity sensor negative events trigger as user activity.
-            // temporarily set mUserActivityAllowed to true so this will work
-            // even when the keyguard is on.
-            mProximitySensorActive = false;
-            if (DEBUG_PROXIMITY_SENSOR) {
-                Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="
-                        + mProxIgnoredBecauseScreenTurnedOff);
-            }
-            if (!mProxIgnoredBecauseScreenTurnedOff) {
-                forceUserActivityLocked();
+
+        pw.println("POWER MANAGER (dumpsys power)\n");
+
+        final DisplayPowerController dpc;
+        synchronized (mLock) {
+            pw.println("Power Manager State:");
+            pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
+            pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
+            pw.println("  mIsPowered=" + mIsPowered);
+            pw.println("  mStayOn=" + mStayOn);
+            pw.println("  mBootCompleted=" + mBootCompleted);
+            pw.println("  mSystemReady=" + mSystemReady);
+            pw.println("  mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
+            pw.println("  mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary));
+            pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
+            pw.println("  mSandmanScheduled=" + mSandmanScheduled);
+            pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
+            pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
+            pw.println("  mSendWakeUpFinishedNotificationWhenReady="
+                    + mSendWakeUpFinishedNotificationWhenReady);
+            pw.println("  mSendGoToSleepFinishedNotificationWhenReady="
+                    + mSendGoToSleepFinishedNotificationWhenReady);
+            pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
+            pw.println("  mLastUserActivityTimeNoChangeLights="
+                    + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
+            pw.println("  mDisplayReady=" + mDisplayReady);
+            pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
+
+            pw.println();
+            pw.println("Settings and Configuration:");
+            pw.println("  mDreamsSupportedConfig=" + mDreamsSupportedConfig);
+            pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
+            pw.println("  mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
+            pw.println("  mMaximumScreenOffTimeoutFromDeviceAdmin="
+                    + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
+                    + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
+            pw.println("  mStayOnWhilePluggedInSetting=" + mStayOnWhilePluggedInSetting);
+            pw.println("  mScreenBrightnessSetting=" + mScreenBrightnessSetting);
+            pw.println("  mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
+            pw.println("  mScreenBrightnessOverrideFromWindowManager="
+                    + mScreenBrightnessOverrideFromWindowManager);
+            pw.println("  mTemporaryScreenBrightnessSettingOverride="
+                    + mTemporaryScreenBrightnessSettingOverride);
+            pw.println("  mScreenBrightnessSettingMinimum=" + mScreenBrightnessSettingMinimum);
+            pw.println("  mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
+            pw.println("  mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
+
+            pw.println();
+            pw.println("Wake Locks: size=" + mWakeLocks.size());
+            for (WakeLock wl : mWakeLocks) {
+                pw.println("  " + wl);
             }
 
-            if (mProximityWakeLockCount == 0) {
-                // disable sensor if we have no listeners left after proximity negative
-                disableProximityLockLocked();
+            pw.println();
+            pw.println("Suspend Blockers: size=" + mSuspendBlockers.size());
+            for (SuspendBlocker sb : mSuspendBlockers) {
+                pw.println("  " + sb);
+            }
+
+            dpc = mDisplayPowerController;
+        }
+
+        if (dpc != null) {
+            dpc.dump(pw);
+        }
+    }
+
+    private SuspendBlocker createSuspendBlockerLocked(String name) {
+        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
+        mSuspendBlockers.add(suspendBlocker);
+        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_NAPPING:
+                return "Napping";
+            default:
+                return Integer.toString(wakefulness);
+        }
+    }
+
+    private static WorkSource copyWorkSource(WorkSource workSource) {
+        return workSource != null ? new WorkSource(workSource) : null;
+    }
+
+    private final class BatteryReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mLock) {
+                handleBatteryStateChangedLocked();
             }
         }
     }
 
-    private void enableLightSensorLocked(boolean enable) {
-        if (DEBUG_LIGHT_SENSOR) {
-            Slog.d(TAG, "enableLightSensorLocked enable=" + enable
-                    + " mLightSensorEnabled=" + mLightSensorEnabled
-                    + " mAutoBrightessEnabled=" + mAutoBrightessEnabled
-                    + " mWaitingForFirstLightSensor=" + mWaitingForFirstLightSensor);
+    private final class BootCompletedReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mLock) {
+                handleBootCompletedLocked();
+            }
         }
-        if (!mAutoBrightessEnabled) {
-            enable = false;
+    }
+
+    private final class DockReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mLock) {
+                int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                handleDockStateChangedLocked(dockState);
+            }
         }
-        if (mSensorManager != null && mLightSensorEnabled != enable) {
-            mLightSensorEnabled = enable;
-            // clear calling identity so sensor manager battery stats are accurate
-            long identity = Binder.clearCallingIdentity();
+    }
+
+    private final class SettingsObserver extends ContentObserver {
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            synchronized (mLock) {
+                handleSettingsChangedLocked();
+            }
+        }
+    }
+
+    private final WindowManagerPolicy.ScreenOnListener mScreenOnListener =
+            new WindowManagerPolicy.ScreenOnListener() {
+        @Override
+        public void onScreenOn() {
+        }
+    };
+
+    /**
+     * Handler for asynchronous operations performed by the power manager.
+     */
+    private final class PowerManagerHandler extends Handler {
+        public PowerManagerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_USER_ACTIVITY_TIMEOUT:
+                    handleUserActivityTimeout();
+                    break;
+                case MSG_SANDMAN:
+                    handleSandman();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Represents a wake lock that has been acquired by an application.
+     */
+    private final class WakeLock implements IBinder.DeathRecipient {
+        public final IBinder mLock;
+        public int mFlags;
+        public String mTag;
+        public WorkSource mWorkSource;
+        public int mOwnerUid;
+        public int mOwnerPid;
+
+        public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
+                int ownerUid, int ownerPid) {
+            mLock = lock;
+            mFlags = flags;
+            mTag = tag;
+            mWorkSource = copyWorkSource(workSource);
+            mOwnerUid = ownerUid;
+            mOwnerPid = ownerPid;
+        }
+
+        @Override
+        public void binderDied() {
+            PowerManagerService.this.handleWakeLockDeath(this);
+        }
+
+        public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
+                int ownerUid, int ownerPid) {
+            return mFlags == flags
+                    && mTag.equals(tag)
+                    && hasSameWorkSource(workSource)
+                    && mOwnerUid == ownerUid
+                    && mOwnerPid == ownerPid;
+        }
+
+        public void updateProperties(int flags, String tag, WorkSource workSource,
+                int ownerUid, int ownerPid) {
+            mFlags = flags;
+            mTag = tag;
+            updateWorkSource(workSource);
+            mOwnerUid = ownerUid;
+            mOwnerPid = ownerPid;
+        }
+
+        public boolean hasSameWorkSource(WorkSource workSource) {
+            return Objects.equal(mWorkSource, workSource);
+        }
+
+        public void updateWorkSource(WorkSource workSource) {
+            mWorkSource = copyWorkSource(workSource);
+        }
+
+        @Override
+        public String toString() {
+            return getLockLevelString()
+                    + " '" + mTag + "'" + getLockFlagsString()
+                    + " (uid=" + mOwnerUid + ", pid=" + mOwnerPid + ", ws=" + mWorkSource + ")";
+        }
+
+        private String getLockLevelString() {
+            switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+                case PowerManager.FULL_WAKE_LOCK:
+                    return "FULL_WAKE_LOCK                ";
+                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+                    return "SCREEN_BRIGHT_WAKE_LOCK       ";
+                case PowerManager.SCREEN_DIM_WAKE_LOCK:
+                    return "SCREEN_DIM_WAKE_LOCK          ";
+                case PowerManager.PARTIAL_WAKE_LOCK:
+                    return "PARTIAL_WAKE_LOCK             ";
+                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
+                default:
+                    return "???                           ";
+            }
+        }
+
+        private String getLockFlagsString() {
+            String result = "";
+            if ((mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {
+                result += " ACQUIRE_CAUSES_WAKEUP";
+            }
+            if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
+                result += " ON_AFTER_RELEASE";
+            }
+            return result;
+        }
+    }
+
+    private final class SuspendBlockerImpl implements SuspendBlocker {
+        private final String mName;
+        private int mReferenceCount;
+
+        public SuspendBlockerImpl(String name) {
+            mName = name;
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
             try {
-                if (enable) {
-                    // reset our highest value when reenabling
-                    mHighestLightSensorValue = -1;
-                    // force recompute of backlight values
-                    final int value = (int)mLightSensorValue;
-                    if (value >= 0) {
-                        mLightSensorValue = -1;
-                        handleLightSensorValue(value, true);
-                    }
-                    mSensorManager.registerListener(mLightListener, mLightSensor,
-                            LIGHT_SENSOR_RATE);
-                } else {
-                    mSensorManager.unregisterListener(mLightListener);
-                    mHandler.removeCallbacks(mAutoBrightnessTask);
-                    mLightSensorPendingDecrease = false;
-                    mLightSensorPendingIncrease = false;
+                if (mReferenceCount != 0) {
+                    Log.wtf(TAG, "Suspend blocker \"" + mName
+                            + "\" was finalized without being released!");
+                    mReferenceCount = 0;
+                    nativeReleaseSuspendBlocker(mName);
                 }
             } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    SensorEventListener mProximityListener = new SensorEventListener() {
-        public void onSensorChanged(SensorEvent event) {
-            long milliseconds = SystemClock.elapsedRealtime();
-            synchronized (mLocks) {
-                float distance = event.values[0];
-                long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
-                mLastProximityEventTime = milliseconds;
-                mHandler.removeCallbacks(mProximityTask);
-                boolean proximityTaskQueued = false;
-
-                // compare against getMaximumRange to support sensors that only return 0 or 1
-                boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
-                        distance < mProximitySensor.getMaximumRange());
-
-                if (DEBUG_PROXIMITY_SENSOR) {
-                    Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
-                }
-                if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
-                    // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
-                    mProximityPendingValue = (active ? 1 : 0);
-                    mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
-                    proximityTaskQueued = true;
-                } else {
-                    // process the value immediately
-                    mProximityPendingValue = -1;
-                    proximityChangedLocked(active);
-                }
-
-                // update mProximityPartialLock state
-                boolean held = mProximityPartialLock.isHeld();
-                if (!held && proximityTaskQueued) {
-                    // hold wakelock until mProximityTask runs
-                    mProximityPartialLock.acquire();
-                } else if (held && !proximityTaskQueued) {
-                    mProximityPartialLock.release();
-                }
+                super.finalize();
             }
         }
 
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            // ignore
-        }
-    };
-
-    private void handleLightSensorValue(int value, boolean immediate) {
-        long milliseconds = SystemClock.elapsedRealtime();
-        if (mLightSensorValue == -1
-                || milliseconds < mLastScreenOnTime + mLightSensorWarmupTime
-                || mWaitingForFirstLightSensor) {
-            // process the value immediately if screen has just turned on
-            mHandler.removeCallbacks(mAutoBrightnessTask);
-            mLightSensorPendingDecrease = false;
-            mLightSensorPendingIncrease = false;
-            lightSensorChangedLocked(value, immediate);
-        } else {
-            if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
-                    (value < mLightSensorValue && mLightSensorPendingIncrease) ||
-                    (value == mLightSensorValue) ||
-                    (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
-                // delay processing to debounce the sensor
-                mHandler.removeCallbacks(mAutoBrightnessTask);
-                mLightSensorPendingDecrease = (value < mLightSensorValue);
-                mLightSensorPendingIncrease = (value > mLightSensorValue);
-                if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
-                    mLightSensorPendingValue = value;
-                    mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
-                }
-            } else {
-                mLightSensorPendingValue = value;
-            }
-        }
-    }
-
-    SensorEventListener mLightListener = new SensorEventListener() {
         @Override
-        public void onSensorChanged(SensorEvent event) {
-            if (DEBUG_LIGHT_SENSOR) {
-                Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
-            }
-            synchronized (mLocks) {
-                // ignore light sensor while screen is turning off
-                if (isScreenTurningOffLocked()) {
-                    return;
-                }
-                handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
-                if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) {
-                    if (DEBUG_LIGHT_ANIMATION) {
-                        Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor.");
-                    }
-                    mWaitingForFirstLightSensor = false;
+        public void acquire() {
+            synchronized (this) {
+                mReferenceCount += 1;
+                if (mReferenceCount == 1) {
+                    nativeAcquireSuspendBlocker(mName);
                 }
             }
         }
 
         @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            // ignore
+        public void release() {
+            synchronized (this) {
+                mReferenceCount -= 1;
+                if (mReferenceCount == 0) {
+                    nativeReleaseSuspendBlocker(mName);
+                } else if (mReferenceCount < 0) {
+                    Log.wtf(TAG, "Suspend blocker \"" + mName
+                            + "\" was released without being acquired!", new Throwable());
+                    mReferenceCount = 0;
+                }
+            }
         }
-    };
+
+        @Override
+        public String toString() {
+            synchronized (this) {
+                return mName + ": ref count=" + mReferenceCount;
+            }
+        }
+    }
 }
diff --git a/services/java/com/android/server/power/RampAnimator.java b/services/java/com/android/server/power/RampAnimator.java
new file mode 100644
index 0000000..6f063c3
--- /dev/null
+++ b/services/java/com/android/server/power/RampAnimator.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import android.animation.ValueAnimator;
+import android.util.IntProperty;
+import android.view.Choreographer;
+
+/**
+ * A custom animator that progressively updates a property value at
+ * a given variable rate until it reaches a particular target value.
+ */
+final class RampAnimator<T> {
+    private final T mObject;
+    private final IntProperty<T> mProperty;
+    private final Choreographer mChoreographer;
+
+    private int mCurrentValue;
+    private int mTargetValue;
+    private int mRate;
+
+    private boolean mAnimating;
+    private float mAnimatedValue; // higher precision copy of mCurrentValue
+    private long mLastFrameTimeNanos;
+
+    private boolean mFirstTime = true;
+
+    public RampAnimator(T object, IntProperty<T> property) {
+        mObject = object;
+        mProperty = property;
+        mChoreographer = Choreographer.getInstance();
+    }
+
+    /**
+     * Starts animating towards the specified value.
+     *
+     * If this is the first time the property is being set, the value jumps
+     * directly to the target.
+     *
+     * @param target The target value.
+     * @param rate The convergence rate, in units per second.
+     * @return True if the target differs from the previous target.
+     */
+    public boolean animateTo(int target, int rate) {
+        // Immediately jump to the target the first time.
+        if (mFirstTime) {
+            mFirstTime = false;
+            mProperty.setValue(mObject, target);
+            mCurrentValue = target;
+            return true;
+        }
+
+        // Adjust the rate based on the closest target.
+        // If a faster rate is specified, then use the new rate so that we converge
+        // more rapidly based on the new request.
+        // If a slower rate is specified, then use the new rate only if the current
+        // value is somewhere in between the new and the old target meaning that
+        // we will be ramping in a different direction to get there.
+        // Otherwise, continue at the previous rate.
+        if (!mAnimating
+                || rate > mRate
+                || (target <= mCurrentValue && mCurrentValue <= mTargetValue)
+                || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
+            mRate = rate;
+        }
+
+        final boolean changed = (mTargetValue != target);
+        mTargetValue = target;
+
+        // Start animating.
+        if (!mAnimating && target != mCurrentValue) {
+            mAnimating = true;
+            mAnimatedValue = mCurrentValue;
+            mLastFrameTimeNanos = System.nanoTime();
+            postCallback();
+        }
+
+        return changed;
+    }
+
+    private void postCallback() {
+        mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null);
+    }
+
+    private final Runnable mCallback = new Runnable() {
+        @Override // Choreographer callback
+        public void run() {
+            final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
+            final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
+                    * 0.000000001f;
+            final float amount = timeDelta * mRate / ValueAnimator.getDurationScale();
+            mLastFrameTimeNanos = frameTimeNanos;
+
+            // Advance the animated value towards the target at the specified rate
+            // and clamp to the target. This gives us the new current value but
+            // we keep the animated value around to allow for fractional increments
+            // towards the target.
+            int oldCurrentValue = mCurrentValue;
+            if (mTargetValue > mCurrentValue) {
+                mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);
+            } else {
+                mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue);
+            }
+            mCurrentValue = (int)Math.round(mAnimatedValue);
+
+            if (oldCurrentValue != mCurrentValue) {
+                mProperty.setValue(mObject, mCurrentValue);
+            }
+
+            if (mTargetValue != mCurrentValue) {
+                postCallback();
+            } else {
+                mAnimating = false;
+            }
+        }
+    };
+}
diff --git a/services/java/com/android/server/power/SuspendBlocker.java b/services/java/com/android/server/power/SuspendBlocker.java
new file mode 100644
index 0000000..70b278a
--- /dev/null
+++ b/services/java/com/android/server/power/SuspendBlocker.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+/**
+ * Low-level suspend blocker mechanism equivalent to holding a partial wake lock.
+ *
+ * This interface is used internally to avoid introducing internal dependencies
+ * on the high-level wake lock mechanism.
+ */
+interface SuspendBlocker {
+    /**
+     * Acquires the suspend blocker.
+     * Prevents the CPU from going to sleep.
+     *
+     * Calls to acquire() nest and must be matched by the same number
+     * of calls to release().
+     */
+    void acquire();
+
+    /**
+     * Releases the suspend blocker.
+     * Allows the CPU to go to sleep if no other suspend blockers are held.
+     *
+     * It is an error to call release() if the suspend blocker has not been acquired.
+     * The system may crash.
+     */
+    void release();
+}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 680ae4c0..40a9eed 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -57,6 +57,7 @@
 import android.app.IActivityManager;
 import android.app.StatusBarManager;
 import android.app.admin.DevicePolicyManager;
+import android.animation.ValueAnimator;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -854,7 +855,7 @@
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
             android.os.Process.setCanSelfBackground(false);
-            mPolicy.init(mContext, mService, mService, mPM);
+            mPolicy.init(mContext, mService, mService);
             mService.mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
                     * TYPE_LAYER_MULTIPLIER
                     + TYPE_LAYER_OFFSET;
@@ -900,8 +901,8 @@
                 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
         mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
                 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
-        mAnimatorDurationScale = Settings.System.getFloat(context.getContentResolver(),
-                Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale);
+        setAnimatorDurationScale(Settings.System.getFloat(context.getContentResolver(),
+                Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
 
         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
         IntentFilter filter = new IntentFilter();
@@ -909,7 +910,7 @@
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
         mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
-                | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
+                | PowerManager.ON_AFTER_RELEASE, PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
         mInputManager = new InputManagerService(context, mInputMonitor);
@@ -5160,7 +5161,7 @@
                 mTransitionAnimationScale = fixScale(scales[1]);
             }
             if (scales.length >= 3) {
-                mAnimatorDurationScale = fixScale(scales[2]);
+                setAnimatorDurationScale(fixScale(scales[2]));
             }
         }
 
@@ -5168,6 +5169,11 @@
         mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
     }
 
+    private void setAnimatorDurationScale(float scale) {
+        mAnimatorDurationScale = scale;
+        ValueAnimator.setDurationScale(scale);
+    }
+
     public float getAnimationScale(int which) {
         switch (which) {
             case 0: return mWindowAnimationScale;
@@ -9068,16 +9074,16 @@
         setHoldScreenLocked(mInnerFields.mHoldScreen != null);
         if (!mDisplayFrozen) {
             if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
-                mPowerManager.setScreenBrightnessOverride(-1);
+                mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
             } else {
-                mPowerManager.setScreenBrightnessOverride((int)
-                        (mInnerFields.mScreenBrightness * PowerManager.BRIGHTNESS_ON));
+                mPowerManager.setScreenBrightnessOverrideFromWindowManager(
+                        toBrightnessOverride(mInnerFields.mScreenBrightness));
             }
             if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
-                mPowerManager.setButtonBrightnessOverride(-1);
+                mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
             } else {
-                mPowerManager.setButtonBrightnessOverride((int)
-                        (mInnerFields.mButtonBrightness * PowerManager.BRIGHTNESS_ON));
+                mPowerManager.setButtonBrightnessOverrideFromWindowManager(
+                        toBrightnessOverride(mInnerFields.mButtonBrightness));
             }
         }
         if (mInnerFields.mHoldScreen != mHoldingScreenOn) {
@@ -9088,8 +9094,7 @@
 
         if (mTurnOnScreen) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
-                    PowerManager.USER_ACTIVITY_EVENT_BUTTON, true);
+            mPowerManager.wakeUp(SystemClock.uptimeMillis());
             mTurnOnScreen = false;
         }
 
@@ -9120,6 +9125,10 @@
         }
     }
 
+    private int toBrightnessOverride(float value) {
+        return (int)(value * PowerManager.BRIGHTNESS_ON);
+    }
+
     void checkDrawnWindowsLocked() {
         if (mWaitingForDrawn.size() > 0) {
             for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
diff --git a/services/jni/com_android_server_LightsService.cpp b/services/jni/com_android_server_LightsService.cpp
index 9ed495195..401e1aa 100644
--- a/services/jni/com_android_server_LightsService.cpp
+++ b/services/jni/com_android_server_LightsService.cpp
@@ -120,7 +120,10 @@
     state.flashOffMS = offMS;
     state.brightnessMode = brightnessMode;
 
-    devices->lights[light]->set_light(devices->lights[light], &state);
+    {
+        ALOGD_IF_SLOW(50, "Excessive delay setting light");
+        devices->lights[light]->set_light(devices->lights[light], &state);
+    }
 }
 
 static JNINativeMethod method_table[] = {
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 35c2142..701b15a 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -143,7 +143,7 @@
 
 enum {
     WM_ACTION_PASS_TO_USER = 1,
-    WM_ACTION_POKE_USER_ACTIVITY = 2,
+    WM_ACTION_WAKE_UP = 2,
     WM_ACTION_GO_TO_SLEEP = 4,
 };
 
@@ -899,11 +899,11 @@
         android_server_PowerManagerService_goToSleep(when);
     }
 
-    if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
+    if (wmActions & WM_ACTION_WAKE_UP) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
-        ALOGD("handleInterceptActions: Poking user activity.");
+        ALOGD("handleInterceptActions: Waking up.");
 #endif
-        android_server_PowerManagerService_userActivity(when, USER_ACTIVITY_EVENT_BUTTON);
+        android_server_PowerManagerService_wakeUp(when);
     }
 
     if (wmActions & WM_ACTION_PASS_TO_USER) {
diff --git a/services/jni/com_android_server_power_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
index 8307d25..3f3970b 100644
--- a/services/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -21,6 +21,8 @@
 #include "JNIHelp.h"
 #include "jni.h"
 
+#include <ScopedUtfChars.h>
+
 #include <limits.h>
 
 #include <android_runtime/AndroidRuntime.h>
@@ -28,6 +30,7 @@
 #include <utils/Timers.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
+#include <utils/Log.h>
 #include <hardware/power.h>
 #include <hardware_legacy/power.h>
 #include <cutils/android_reboot.h>
@@ -42,8 +45,9 @@
 // ----------------------------------------------------------------------------
 
 static struct {
-    jmethodID goToSleep;
-    jmethodID userActivity;
+    jmethodID wakeUpFromNative;
+    jmethodID goToSleepFromNative;
+    jmethodID userActivityFromNative;
 } gPowerManagerServiceClassInfo;
 
 // ----------------------------------------------------------------------------
@@ -106,9 +110,21 @@
 
         JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-        env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivity,
-                nanoseconds_to_milliseconds(eventTime), false, eventType, false);
-        checkAndClearExceptionFromCallback(env, "userActivity");
+        env->CallVoidMethod(gPowerManagerServiceObj,
+                gPowerManagerServiceClassInfo.userActivityFromNative,
+                nanoseconds_to_milliseconds(eventTime), eventType, 0);
+        checkAndClearExceptionFromCallback(env, "userActivityFromNative");
+    }
+}
+
+void android_server_PowerManagerService_wakeUp(nsecs_t eventTime) {
+    if (gPowerManagerServiceObj) {
+        JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+        env->CallVoidMethod(gPowerManagerServiceObj,
+                gPowerManagerServiceClassInfo.wakeUpFromNative,
+                nanoseconds_to_milliseconds(eventTime));
+        checkAndClearExceptionFromCallback(env, "wakeUpFromNative");
     }
 }
 
@@ -116,9 +132,10 @@
     if (gPowerManagerServiceObj) {
         JNIEnv* env = AndroidRuntime::getJNIEnv();
 
-        env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep,
-                nanoseconds_to_milliseconds(eventTime));
-        checkAndClearExceptionFromCallback(env, "goToSleep");
+        env->CallVoidMethod(gPowerManagerServiceObj,
+                gPowerManagerServiceClassInfo.goToSleepFromNative,
+                nanoseconds_to_milliseconds(eventTime), 0);
+        checkAndClearExceptionFromCallback(env, "goToSleepFromNative");
     }
 }
 
@@ -137,68 +154,62 @@
 }
 
 static void nativeSetPowerState(JNIEnv* env,
-        jobject serviceObj, jboolean screenOn, jboolean screenBright) {
+        jclass clazz, jboolean screenOn, jboolean screenBright) {
     AutoMutex _l(gPowerManagerLock);
     gScreenOn = screenOn;
     gScreenBright = screenBright;
 }
 
-static void nativeStartSurfaceFlingerAnimation(JNIEnv* env,
-        jobject obj, jint mode) {
-    // this is not handled by surfaceflinger anymore
+static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
+    ScopedUtfChars name(env, nameStr);
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
 }
 
-static void nativeAcquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) {
-    if (idObj == NULL) {
-        jniThrowNullPointerException(env, "id is null");
-        return;
-    }
-
-    const char *id = env->GetStringUTFChars(idObj, NULL);
-
-    acquire_wake_lock(lock, id);
-
-    env->ReleaseStringUTFChars(idObj, id);
+static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
+    ScopedUtfChars name(env, nameStr);
+    release_wake_lock(name.c_str());
 }
 
-static void nativeReleaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj) {
-    if (idObj == NULL) {
-        jniThrowNullPointerException(env, "id is null");
-        return ;
-    }
-
-    const char *id = env->GetStringUTFChars(idObj, NULL);
-
-    release_wake_lock(id);
-
-    env->ReleaseStringUTFChars(idObj, id);
-
-}
-
-static int nativeSetScreenState(JNIEnv *env, jobject clazz, jboolean on) {
+static void nativeSetScreenState(JNIEnv *env, jclass clazz, jboolean on) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (on) {
-        autosuspend_disable();
+        {
+            ALOGD_IF_SLOW(50, "Excessive delay in autosuspend_disable() while turning screen on");
+            autosuspend_disable();
+        }
+
         if (gPowerModule) {
+            ALOGD_IF_SLOW(10, "Excessive delay in setInteractive(true) while turning screen on");
             gPowerModule->setInteractive(gPowerModule, true);
         }
-        s->unblank();
+
+        {
+            ALOGD_IF_SLOW(20, "Excessive delay in unblank() while turning screen on");
+            s->unblank();
+        }
     } else {
-        s->blank();
+        {
+            ALOGD_IF_SLOW(20, "Excessive delay in blank() while turning screen off");
+            s->blank();
+        }
+
         if (gPowerModule) {
+            ALOGD_IF_SLOW(10, "Excessive delay in setInteractive(false) while turning screen off");
             gPowerModule->setInteractive(gPowerModule, false);
         }
-        autosuspend_enable();
-    }
 
-    return 0;
+        {
+            ALOGD_IF_SLOW(50, "Excessive delay in autosuspend_enable() while turning screen off");
+            autosuspend_enable();
+        }
+    }
 }
 
-static void nativeShutdown(JNIEnv *env, jobject clazz) {
+static void nativeShutdown(JNIEnv *env, jclass clazz) {
     android_reboot(ANDROID_RB_POWEROFF, 0, 0);
 }
 
-static void nativeReboot(JNIEnv *env, jobject clazz, jstring reason) {
+static void nativeReboot(JNIEnv *env, jclass clazz, jstring reason) {
     if (reason == NULL) {
         android_reboot(ANDROID_RB_RESTART, 0, 0);
     } else {
@@ -218,13 +229,11 @@
             (void*) nativeInit },
     { "nativeSetPowerState", "(ZZ)V",
             (void*) nativeSetPowerState },
-    { "nativeStartSurfaceFlingerAnimation", "(I)V",
-            (void*) nativeStartSurfaceFlingerAnimation },
-    { "nativeAcquireWakeLock", "(ILjava/lang/String;)V",
-            (void*) nativeAcquireWakeLock },
-    { "nativeReleaseWakeLock", "(Ljava/lang/String;)V",
-            (void*) nativeReleaseWakeLock },
-    { "nativeSetScreenState", "(Z)I",
+    { "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
+            (void*) nativeAcquireSuspendBlocker },
+    { "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
+            (void*) nativeReleaseSuspendBlocker },
+    { "nativeSetScreenState", "(Z)V",
             (void*) nativeSetScreenState },
     { "nativeShutdown", "()V",
             (void*) nativeShutdown },
@@ -254,11 +263,14 @@
     jclass clazz;
     FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
 
-    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, clazz,
-            "goToSleep", "(J)V");
+    GET_METHOD_ID(gPowerManagerServiceClassInfo.wakeUpFromNative, clazz,
+            "wakeUpFromNative", "(J)V");
 
-    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, clazz,
-            "userActivity", "(JZIZ)V");
+    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleepFromNative, clazz,
+            "goToSleepFromNative", "(JI)V");
+
+    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
+            "userActivityFromNative", "(JII)V");
 
     // Initialize
     for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
diff --git a/services/jni/com_android_server_power_PowerManagerService.h b/services/jni/com_android_server_power_PowerManagerService.h
index cc3b5ef5..0808b80 100644
--- a/services/jni/com_android_server_power_PowerManagerService.h
+++ b/services/jni/com_android_server_power_PowerManagerService.h
@@ -27,6 +27,7 @@
 extern bool android_server_PowerManagerService_isScreenOn();
 extern bool android_server_PowerManagerService_isScreenBright();
 extern void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType);
+extern void android_server_PowerManagerService_wakeUp(nsecs_t eventTime);
 extern void android_server_PowerManagerService_goToSleep(nsecs_t eventTime);
 
 } // namespace android
diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
index 31a1cf5a..e38bb6c 100644
--- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
@@ -16,32 +16,15 @@
 
 package com.android.statusbartest;
 
-import android.app.ListActivity;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.widget.ArrayAdapter;
-import android.view.View;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IPowerManager;
-import android.widget.ListView;
-import android.content.Intent;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.StatusBarManager;
 import android.os.RemoteException;
-import android.os.Vibrator;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.LocalPowerManager;
 import android.os.ServiceManager;
-import android.util.Log;
-import android.net.Uri;
-import android.os.SystemClock;
-import android.widget.RemoteViews;
-import android.widget.Toast;
 import android.os.PowerManager;
 
 public class PowerTest extends TestActivity
@@ -101,6 +84,28 @@
                 mProx.release(PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
             }
         },
+        new Test("Enable proximity, wait 5 seconds then disable") {
+            public void run() {
+                mProx.acquire();
+                mHandler.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        mProx.release();
+                    }
+                }, 5000);
+            }
+        },
+        new Test("Enable proximity, wait 5 seconds then disable  (WAIT_FOR_PROXIMITY_NEGATIVE)") {
+            public void run() {
+                mProx.acquire();
+                mHandler.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        mProx.release(PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
+                    }
+                }, 5000);
+            }
+        },
         new Test("Touch events don't poke") {
             public void run() {
                 mPokeState |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 0a1191b..292e4fc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -440,7 +440,7 @@
         }
 
         if (POWER_SERVICE.equals(service)) {
-            return new PowerManager(new BridgePowerManager(), new Handler());
+            return new PowerManager(this, new BridgePowerManager(), new Handler());
         }
 
         throw new UnsupportedOperationException("Unsupported Service: " + service);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 6071a6b..0c85204 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -39,7 +39,7 @@
     }
 
     @Override
-    public void acquireWakeLock(int arg0, IBinder arg1, String arg2, WorkSource arg3)
+    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, WorkSource arg3)
             throws RemoteException {
         // pass for now.
     }
@@ -55,18 +55,7 @@
     }
 
     @Override
-    public int getSupportedWakeLockFlags() throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void goToSleep(long arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void goToSleepWithReason(long arg0, int arg1) throws RemoteException {
+    public void goToSleep(long arg0, int arg1) throws RemoteException {
         // pass for now.
     }
 
@@ -91,17 +80,17 @@
     }
 
     @Override
-    public void setAutoBrightnessAdjustment(float arg0) throws RemoteException {
+    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
         // pass for now.
     }
 
     @Override
-    public void setBacklightBrightness(int arg0) throws RemoteException {
+    public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
         // pass for now.
     }
 
     @Override
-    public void setMaximumScreenOffTimeount(int arg0) throws RemoteException {
+    public void setMaximumScreenOffTimeoutFromDeviceAdmin(int arg0) throws RemoteException {
         // pass for now.
     }
 
@@ -121,12 +110,18 @@
     }
 
     @Override
-    public void userActivity(long arg0, boolean arg1) throws RemoteException {
+    public boolean isWakeLockLevelSupported(int level) throws RemoteException {
+        // pass for now.
+        return true;
+    }
+
+    @Override
+    public void userActivity(long time, int event, int flags) throws RemoteException {
         // pass for now.
     }
 
     @Override
-    public void userActivityWithForce(long arg0, boolean arg1, boolean arg2) throws RemoteException {
+    public void wakeUp(long time) throws RemoteException {
         // pass for now.
     }
 }
