Merge "Move display power controller to display manager service."
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 8430973..03fa1d5 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -16,6 +16,9 @@
 
 package android.hardware.display;
 
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.PowerManager;
 import android.view.DisplayInfo;
 
 /**
@@ -25,6 +28,36 @@
  */
 public abstract class DisplayManagerInternal {
     /**
+     * Called by the power manager to initialize power management facilities.
+     */
+    public abstract void initPowerManagement(DisplayPowerCallbacks callbacks,
+            Handler handler, SensorManager sensorManager);
+
+    /**
+     * Called by the power manager to request a new power state.
+     * <p>
+     * The display power controller makes a copy of the provided object and then
+     * begins adjusting the power state to match what was requested.
+     * </p>
+     *
+     * @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 DisplayPowerCallbacks#onStateChanged()}
+     * then try the request again later until the state converges.
+     */
+    public abstract boolean requestPowerState(DisplayPowerRequest request,
+            boolean waitForNegativeProximity);
+
+    /**
+     * Returns true if the proximity sensor screen-off function is available.
+     */
+    public abstract boolean isProximitySensorAvailable();
+
+    /**
      * Called by the power manager to blank all displays.
      */
     public abstract void blankAllDisplaysFromPowerManager();
@@ -99,6 +132,137 @@
             boolean inTraversal);
 
     /**
+     * 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 DisplayPowerController to manage the
+     * details of how the transitions between states should occur.  The goal is for
+     * the PowerManagerService to focus on the global power state and not
+     * have to micro-manage screen off animations, auto-brightness and other effects.
+     */
+    public static final class DisplayPowerRequest {
+        public static final int SCREEN_STATE_OFF = 0;
+        public static final int SCREEN_STATE_DOZE = 1;
+        public static final int SCREEN_STATE_DIM = 2;
+        public static final int SCREEN_STATE_BRIGHT = 3;
+
+        // The requested minimum screen power state: off, doze, 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;
+
+        // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter).
+        public float screenAutoBrightnessAdjustment;
+
+        // If true, enables automatic brightness control.
+        public boolean useAutoBrightness;
+
+        // If true, prevents the screen from completely turning on if it is currently off.
+        // The display does not enter a "ready" state if this flag is true and screen on is
+        // blocked.  The window manager policy blocks screen on while it prepares the keyguard to
+        // prevent the user from seeing intermediate updates.
+        //
+        // Technically, we may not block the screen itself from turning on (because that introduces
+        // extra unnecessary latency) but we do prevent content on screen from becoming
+        // visible to the user.
+        public boolean blockScreenOn;
+
+        public DisplayPowerRequest() {
+            screenState = SCREEN_STATE_BRIGHT;
+            useProximitySensor = false;
+            screenBrightness = PowerManager.BRIGHTNESS_ON;
+            screenAutoBrightnessAdjustment = 0.0f;
+            useAutoBrightness = false;
+            blockScreenOn = false;
+        }
+
+        public DisplayPowerRequest(DisplayPowerRequest other) {
+            copyFrom(other);
+        }
+
+        // Returns true if we want the screen on in any mode, including doze.
+        public boolean wantScreenOnAny() {
+            return screenState != SCREEN_STATE_OFF;
+        }
+
+        // Returns true if we want the screen on in a normal mode, excluding doze.
+        // This is usually what we want to tell the rest of the system.  For compatibility
+        // reasons, we pretend the screen is off when dozing.
+        public boolean wantScreenOnNormal() {
+            return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT;
+        }
+
+        public boolean wantLightSensorEnabled() {
+            // Specifically, we don't want the light sensor while dozing.
+            return useAutoBrightness && wantScreenOnNormal();
+        }
+
+        public void copyFrom(DisplayPowerRequest other) {
+            screenState = other.screenState;
+            useProximitySensor = other.useProximitySensor;
+            screenBrightness = other.screenBrightness;
+            screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
+            useAutoBrightness = other.useAutoBrightness;
+            blockScreenOn = other.blockScreenOn;
+        }
+
+        @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
+                    && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
+                    && useAutoBrightness == other.useAutoBrightness
+                    && blockScreenOn == other.blockScreenOn;
+        }
+
+        @Override
+        public int hashCode() {
+            return 0; // don't care
+        }
+
+        @Override
+        public String toString() {
+            return "screenState=" + screenState
+                    + ", useProximitySensor=" + useProximitySensor
+                    + ", screenBrightness=" + screenBrightness
+                    + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+                    + ", useAutoBrightness=" + useAutoBrightness
+                    + ", blockScreenOn=" + blockScreenOn;
+        }
+    }
+
+    /**
+     * Asynchronous callbacks from the power controller to the power manager service.
+     */
+    public interface DisplayPowerCallbacks {
+        void onStateChanged();
+        void onProximityPositive();
+        void onProximityNegative();
+
+        void acquireSuspendBlocker();
+        void releaseSuspendBlocker();
+
+        void blankAllDisplays();
+        void unblankAllDisplays();
+    }
+
+    /**
      * Called within a Surface transaction whenever the size or orientation of a
      * display may have changed.  Provides an opportunity for the client to
      * update the position of its surfaces as part of the same transaction.
diff --git a/services/core/java/com/android/server/power/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
similarity index 98%
rename from services/core/java/com/android/server/power/AutomaticBrightnessController.java
rename to services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 807262a..5fa1584 100644
--- a/services/core/java/com/android/server/power/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.server.power;
+package com.android.server.display;
 
+import com.android.server.LocalServices;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
@@ -25,6 +26,7 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.display.DisplayManagerInternal;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -172,10 +174,10 @@
     private float mLastScreenAutoBrightnessGamma = 1.0f;
 
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
-            TwilightManager twilight, SensorManager sensorManager, Spline autoBrightnessSpline,
+            SensorManager sensorManager, Spline autoBrightnessSpline,
             int lightSensorWarmUpTime, int brightnessMin, int brightnessMax) {
         mCallbacks = callbacks;
-        mTwilight = twilight;
+        mTwilight = LocalServices.getService(TwilightManager.class);
         mSensorManager = sensorManager;
         mScreenAutoBrightnessSpline = autoBrightnessSpline;
         mScreenBrightnessRangeMinimum = brightnessMin;
@@ -198,7 +200,7 @@
         return mScreenAutoBrightness;
     }
 
-    public void updatePowerState(DisplayPowerRequest request) {
+    public void updatePowerState(DisplayManagerInternal.DisplayPowerRequest request) {
         if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment)
                 || setLightSensorEnabled(request.wantLightSensorEnabled())) {
             updateAutoBrightness(false /*sendUpdate*/);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6be6405..693f7d8 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -21,6 +21,7 @@
 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.hardware.SensorManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayManagerInternal;
@@ -172,6 +173,9 @@
     private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
             new CopyOnWriteArrayList<DisplayTransactionListener>();
 
+    // Display power controller.
+    private DisplayPowerController mDisplayPowerController;
+
     // Set to true if all displays have been blanked by the power manager.
     private int mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNKNOWN;
 
@@ -936,6 +940,10 @@
                 pw.println("  " + i + ": mPid=" + callback.mPid
                         + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
             }
+
+            if (mDisplayPowerController != null) {
+                mDisplayPowerController.dump(pw);
+            }
         }
     }
 
@@ -1314,6 +1322,27 @@
 
     private final class LocalService extends DisplayManagerInternal {
         @Override
+        public void initPowerManagement(DisplayPowerCallbacks callbacks, Handler handler,
+                SensorManager sensorManager) {
+            synchronized (mSyncRoot) {
+                mDisplayPowerController = new DisplayPowerController(
+                        mContext, callbacks, handler, sensorManager);
+            }
+        }
+
+        @Override
+        public boolean requestPowerState(DisplayPowerRequest request,
+                boolean waitForNegativeProximity) {
+            return mDisplayPowerController.requestPowerState(request,
+                    waitForNegativeProximity);
+        }
+
+        @Override
+        public boolean isProximitySensorAvailable() {
+            return mDisplayPowerController.isProximitySensorAvailable();
+        }
+
+        @Override
         public void blankAllDisplaysFromPowerManager() {
             blankAllDisplaysFromPowerManagerInternal();
         }
diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
similarity index 90%
rename from services/core/java/com/android/server/power/DisplayPowerController.java
rename to services/core/java/com/android/server/display/DisplayPowerController.java
index 6d3702a..62fb02a 100644
--- a/services/core/java/com/android/server/power/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.server.power;
+package com.android.server.display;
 
+import com.android.internal.app.IBatteryStats;
+import com.android.server.LocalServices;
+import com.android.server.am.BatteryStatsService;
 import com.android.server.lights.LightsManager;
-import com.android.server.twilight.TwilightListener;
-import com.android.server.twilight.TwilightManager;
-import com.android.server.twilight.TwilightState;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
@@ -29,10 +29,13 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.MathUtils;
@@ -80,23 +83,6 @@
     // The minimum reduction in brightness when dimmed.
     private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
 
-    // If true, enables the use of the current time as an auto-brightness adjustment.
-    // The basic idea here is to expand the dynamic range of auto-brightness
-    // when it is especially dark outside.  The light sensor tends to perform
-    // poorly at low light levels so we compensate for it by making an
-    // assumption about the environment.
-    private static final boolean USE_TWILIGHT_ADJUSTMENT =
-            PowerManager.useTwilightAdjustmentFeature();
-
-    // Specifies the maximum magnitude of the time of day adjustment.
-    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
-
-    // The amount of time after or before sunrise over which to start adjusting
-    // the gamma.  We want the change to happen gradually so that it is below the
-    // threshold of perceptibility and so that the adjustment has maximum effect
-    // well after dusk.
-    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
-
     private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250;
     private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400;
 
@@ -120,23 +106,15 @@
 
     private final Object mLock = new Object();
 
-    // Notifier for sending asynchronous notifications.
-    private final Notifier mNotifier;
-
-    // The display suspend blocker.
-    // Held while there are pending state change notifications.
-    private final SuspendBlocker mDisplaySuspendBlocker;
-
-    // The display blanker.
-    private final DisplayBlanker mDisplayBlanker;
-
     // 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;
+    private final DisplayPowerCallbacks mCallbacks;
+
+    // Battery stats.
+    private final IBatteryStats mBatteryStats;
 
     // The lights service.
     private final LightsManager mLights;
@@ -246,18 +224,13 @@
     /**
      * Creates the display power controller.
      */
-    public DisplayPowerController(Looper looper, Context context, Notifier notifier,
-            LightsManager lights, TwilightManager twilight, SensorManager sensorManager,
-            SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,
-            Callbacks callbacks, Handler callbackHandler) {
-        mHandler = new DisplayControllerHandler(looper);
-        mNotifier = notifier;
-        mDisplaySuspendBlocker = displaySuspendBlocker;
-        mDisplayBlanker = displayBlanker;
+    public DisplayPowerController(Context context,
+            DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager) {
+        mHandler = new DisplayControllerHandler(handler.getLooper());
         mCallbacks = callbacks;
-        mCallbackHandler = callbackHandler;
 
-        mLights = lights;
+        mBatteryStats = BatteryStatsService.getService();
+        mLights = LocalServices.getService(LightsManager.class);
         mSensorManager = sensorManager;
 
         final Resources resources = context.getResources();
@@ -297,8 +270,8 @@
                 if (screenBrightness[0] < screenBrightnessRangeMinimum) {
                     screenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightness[0]);
                 }
-                mAutomaticBrightnessController = new AutomaticBrightnessController(this, looper,
-                        twilight, sensorManager, screenAutoBrightnessSpline,
+                mAutomaticBrightnessController = new AutomaticBrightnessController(this,
+                        handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
                         lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
                         mScreenBrightnessRangeMaximum);
             }
@@ -393,7 +366,7 @@
     }
 
     private void initialize() {
-        mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker,
+        mPowerState = new DisplayPowerState(new ElectronBeam(), mCallbacks,
                 mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT));
 
         mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
@@ -409,13 +382,17 @@
         mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
                 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
 
-        // Initialize screen on state.
-        if (mPowerState.isScreenOn()) {
-            mNotifier.onScreenOn();
-        } else {
-            mNotifier.onScreenOff();
+        // Initialize screen state for battery stats.
+        try {
+            if (mPowerState.isScreenOn()) {
+                mBatteryStats.noteScreenOn();
+            } else {
+                mBatteryStats.noteScreenOff();
+            }
+            mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
+        } catch (RemoteException ex) {
+            // same process
         }
-        mNotifier.onScreenBrightness(mPowerState.getScreenBrightness());
     }
 
     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@@ -653,10 +630,14 @@
     private void setScreenOn(boolean on) {
         if (mPowerState.isScreenOn() != on) {
             mPowerState.setScreenOn(on);
-            if (on) {
-                mNotifier.onScreenOn();
-            } else {
-                mNotifier.onScreenOff();
+            try {
+                if (on) {
+                    mBatteryStats.noteScreenOn();
+                } else {
+                    mBatteryStats.noteScreenOff();
+                }
+            } catch (RemoteException ex) {
+                // same process
             }
         }
     }
@@ -668,7 +649,11 @@
 
     private void animateScreenBrightness(int target, int rate) {
         if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
-            mNotifier.onScreenBrightness(target);
+            try {
+                mBatteryStats.noteScreenBrightness(target);
+            } catch (RemoteException ex) {
+                // same process
+            }
         }
     }
 
@@ -753,60 +738,60 @@
     private void clearPendingProximityDebounceTime() {
         if (mPendingProximityDebounceTime >= 0) {
             mPendingProximityDebounceTime = -1;
-            mDisplaySuspendBlocker.release(); // release wake lock
+            mCallbacks.releaseSuspendBlocker(); // release wake lock
         }
     }
 
     private void setPendingProximityDebounceTime(long debounceTime) {
         if (mPendingProximityDebounceTime < 0) {
-            mDisplaySuspendBlocker.acquire(); // acquire wake lock
+            mCallbacks.acquireSuspendBlocker(); // acquire wake lock
         }
         mPendingProximityDebounceTime = debounceTime;
     }
 
     private void sendOnStateChangedWithWakelock() {
-        mDisplaySuspendBlocker.acquire();
-        mCallbackHandler.post(mOnStateChangedRunnable);
+        mCallbacks.acquireSuspendBlocker();
+        mHandler.post(mOnStateChangedRunnable);
     }
 
     private final Runnable mOnStateChangedRunnable = new Runnable() {
         @Override
         public void run() {
             mCallbacks.onStateChanged();
-            mDisplaySuspendBlocker.release();
+            mCallbacks.releaseSuspendBlocker();
         }
     };
 
     private void sendOnProximityPositiveWithWakelock() {
-        mDisplaySuspendBlocker.acquire();
-        mCallbackHandler.post(mOnProximityPositiveRunnable);
+        mCallbacks.acquireSuspendBlocker();
+        mHandler.post(mOnProximityPositiveRunnable);
     }
 
     private final Runnable mOnProximityPositiveRunnable = new Runnable() {
         @Override
         public void run() {
             mCallbacks.onProximityPositive();
-            mDisplaySuspendBlocker.release();
+            mCallbacks.releaseSuspendBlocker();
         }
     };
 
     private void sendOnProximityNegativeWithWakelock() {
-        mDisplaySuspendBlocker.acquire();
-        mCallbackHandler.post(mOnProximityNegativeRunnable);
+        mCallbacks.acquireSuspendBlocker();
+        mHandler.post(mOnProximityNegativeRunnable);
     }
 
     private final Runnable mOnProximityNegativeRunnable = new Runnable() {
         @Override
         public void run() {
             mCallbacks.onProximityNegative();
-            mDisplaySuspendBlocker.release();
+            mCallbacks.releaseSuspendBlocker();
         }
     };
 
     public void dump(final PrintWriter pw) {
         synchronized (mLock) {
             pw.println();
-            pw.println("Display Controller Locked State:");
+            pw.println("Display Power Controller Locked State:");
             pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
             pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
             pw.println("  mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
@@ -816,7 +801,7 @@
         }
 
         pw.println();
-        pw.println("Display Controller Configuration:");
+        pw.println("Display Power Controller Configuration:");
         pw.println("  mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
         pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
         pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
@@ -834,7 +819,7 @@
 
     private void dumpLocal(PrintWriter pw) {
         pw.println();
-        pw.println("Display Controller Thread State:");
+        pw.println("Display Power Controller Thread State:");
         pw.println("  mPowerRequest=" + mPowerRequest);
         pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
 
@@ -913,15 +898,6 @@
         return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
     }
 
-    /**
-     * Asynchronous callbacks from the power controller to the power manager service.
-     */
-    public interface Callbacks {
-        void onStateChanged();
-        void onProximityPositive();
-        void onProximityNegative();
-    }
-
     private final class DisplayControllerHandler extends Handler {
         public DisplayControllerHandler(Looper looper) {
             super(looper, null, true /*async*/);
diff --git a/services/core/java/com/android/server/power/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
similarity index 95%
rename from services/core/java/com/android/server/power/DisplayPowerState.java
rename to services/core/java/com/android/server/display/DisplayPowerState.java
index 8e331ad..e1416d7 100644
--- a/services/core/java/com/android/server/power/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.server.power;
+package com.android.server.display;
 
 import com.android.server.lights.Light;
 
+import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Looper;
@@ -32,8 +33,8 @@
 /**
  * Controls the display power state.
  * <p>
- * 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
+ * This component is similar in nature to a {@link android.view.View} except that it
+ * describes the properties of a display.  When properties are changed, the component
  * invalidates itself and posts a callback to apply the changes in a consistent order.
  * This mechanism enables multiple properties of the display power state to be animated
  * together smoothly by the animation framework.  Some of the work to blank or unblank
@@ -43,8 +44,7 @@
  * that belongs to the {@link DisplayPowerController}.
  * </p><p>
  * We don't need to worry about holding a suspend blocker here because the
- * {@link PowerManagerService} does that for us whenever there is a change
- * in progress.
+ * power manager does that for us whenever there is a change in progress.
  * </p>
  */
 final class DisplayPowerState {
@@ -55,7 +55,7 @@
     private final Handler mHandler;
     private final Choreographer mChoreographer;
     private final ElectronBeam mElectronBeam;
-    private final DisplayBlanker mDisplayBlanker;
+    private final DisplayPowerCallbacks mCallbacks;
     private final Light mBacklight;
     private final PhotonicModulator mPhotonicModulator;
 
@@ -72,11 +72,11 @@
     private Runnable mCleanListener;
 
     public DisplayPowerState(ElectronBeam electronBean,
-            DisplayBlanker displayBlanker, Light backlight) {
+            DisplayPowerCallbacks callbacks, Light backlight) {
         mHandler = new Handler(true /*async*/);
         mChoreographer = Choreographer.getInstance();
         mElectronBeam = electronBean;
-        mDisplayBlanker = displayBlanker;
+        mCallbacks = callbacks;
         mBacklight = backlight;
         mPhotonicModulator = new PhotonicModulator();
 
@@ -403,13 +403,13 @@
                                 + ", backlight=" + backlight);
                     }
                     if (onChanged && on) {
-                        mDisplayBlanker.unblankAllDisplays();
+                        mCallbacks.unblankAllDisplays();
                     }
                     if (backlightChanged) {
                         mBacklight.setBrightness(backlight);
                     }
                     if (onChanged && !on) {
-                        mDisplayBlanker.blankAllDisplays();
+                        mCallbacks.blankAllDisplays();
                     }
                 }
 
diff --git a/services/core/java/com/android/server/power/ElectronBeam.java b/services/core/java/com/android/server/display/ElectronBeam.java
similarity index 99%
rename from services/core/java/com/android/server/power/ElectronBeam.java
rename to services/core/java/com/android/server/display/ElectronBeam.java
index 64921d7..13816bb 100644
--- a/services/core/java/com/android/server/power/ElectronBeam.java
+++ b/services/core/java/com/android/server/display/ElectronBeam.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.power;
+package com.android.server.display;
 
 import java.io.PrintWriter;
 import java.nio.ByteBuffer;
diff --git a/services/core/java/com/android/server/power/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java
similarity index 98%
rename from services/core/java/com/android/server/power/RampAnimator.java
rename to services/core/java/com/android/server/display/RampAnimator.java
index 4a4f080..6688d6a 100644
--- a/services/core/java/com/android/server/power/RampAnimator.java
+++ b/services/core/java/com/android/server/display/RampAnimator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.power;
+package com.android.server.display;
 
 import android.animation.ValueAnimator;
 import android.util.IntProperty;
diff --git a/services/core/java/com/android/server/power/DisplayBlanker.java b/services/core/java/com/android/server/power/DisplayBlanker.java
deleted file mode 100644
index 6072053..0000000
--- a/services/core/java/com/android/server/power/DisplayBlanker.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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;
-
-/**
- * Blanks or unblanks all displays.
- */
-interface DisplayBlanker {
-    public void blankAllDisplays();
-    public void unblankAllDisplays();
-}
diff --git a/services/core/java/com/android/server/power/DisplayPowerRequest.java b/services/core/java/com/android/server/power/DisplayPowerRequest.java
deleted file mode 100644
index c5e46cb..0000000
--- a/services/core/java/com/android/server/power/DisplayPowerRequest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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_DOZE = 1;
-    public static final int SCREEN_STATE_DIM = 2;
-    public static final int SCREEN_STATE_BRIGHT = 3;
-
-    // The requested minimum screen power state: off, doze, 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;
-
-    // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter).
-    public float screenAutoBrightnessAdjustment;
-
-    // If true, enables automatic brightness control.
-    public boolean useAutoBrightness;
-
-    // If true, prevents the screen from completely turning on if it is currently off.
-    // The display does not enter a "ready" state if this flag is true and screen on is
-    // blocked.  The window manager policy blocks screen on while it prepares the keyguard to
-    // prevent the user from seeing intermediate updates.
-    //
-    // Technically, we may not block the screen itself from turning on (because that introduces
-    // extra unnecessary latency) but we do prevent content on screen from becoming
-    // visible to the user.
-    public boolean blockScreenOn;
-
-    public DisplayPowerRequest() {
-        screenState = SCREEN_STATE_BRIGHT;
-        useProximitySensor = false;
-        screenBrightness = PowerManager.BRIGHTNESS_ON;
-        screenAutoBrightnessAdjustment = 0.0f;
-        useAutoBrightness = false;
-        blockScreenOn = false;
-    }
-
-    public DisplayPowerRequest(DisplayPowerRequest other) {
-        copyFrom(other);
-    }
-
-    // Returns true if we want the screen on in any mode, including doze.
-    public boolean wantScreenOnAny() {
-        return screenState != SCREEN_STATE_OFF;
-    }
-
-    // Returns true if we want the screen on in a normal mode, excluding doze.
-    // This is usually what we want to tell the rest of the system.  For compatibility
-    // reasons, we pretend the screen is off when dozing.
-    public boolean wantScreenOnNormal() {
-        return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT;
-    }
-
-    public boolean wantLightSensorEnabled() {
-        // Specifically, we don't want the light sensor while dozing.
-        return useAutoBrightness && wantScreenOnNormal();
-    }
-
-    public void copyFrom(DisplayPowerRequest other) {
-        screenState = other.screenState;
-        useProximitySensor = other.useProximitySensor;
-        screenBrightness = other.screenBrightness;
-        screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
-        useAutoBrightness = other.useAutoBrightness;
-        blockScreenOn = other.blockScreenOn;
-    }
-
-    @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
-                && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
-                && useAutoBrightness == other.useAutoBrightness
-                && blockScreenOn == other.blockScreenOn;
-    }
-
-    @Override
-    public int hashCode() {
-        return 0; // don't care
-    }
-
-    @Override
-    public String toString() {
-        return "screenState=" + screenState
-                + ", useProximitySensor=" + useProximitySensor
-                + ", screenBrightness=" + screenBrightness
-                + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
-                + ", useAutoBrightness=" + useAutoBrightness
-                + ", blockScreenOn=" + blockScreenOn;
-    }
-
-    public static boolean wantScreenOn(int state) {
-        switch(state) {
-            case SCREEN_STATE_DIM:
-            case SCREEN_STATE_BRIGHT:
-                return true;
-        }
-        return false;
-    }
-}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 81af636..ac4a128 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -227,51 +227,6 @@
     }
 
     /**
-     * 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.
      */
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b85a506..90363d7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -24,7 +24,6 @@
 import com.android.server.ServiceThread;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
-import com.android.server.twilight.TwilightManager;
 import com.android.server.Watchdog;
 
 import android.Manifest;
@@ -39,6 +38,7 @@
 import android.hardware.SensorManager;
 import android.hardware.SystemSensorManager;
 import android.hardware.display.DisplayManagerInternal;
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Binder;
@@ -177,7 +177,6 @@
     private PowerManagerHandler mHandler;
     private WindowManagerPolicy mPolicy;
     private Notifier mNotifier;
-    private DisplayPowerController mDisplayPowerController;
     private WirelessChargerDetector mWirelessChargerDetector;
     private SettingsObserver mSettingsObserver;
     private DreamManagerInternal mDreamManager;
@@ -258,9 +257,6 @@
     // screen is coming up.
     private final ScreenOnBlockerImpl mScreenOnBlocker;
 
-    // The display blanker used to turn the screen on or off.
-    private final DisplayBlankerImpl mDisplayBlanker;
-
     // True if systemReady() has been called.
     private boolean mSystemReady;
 
@@ -418,7 +414,6 @@
             mHoldingDisplaySuspendBlocker = true;
 
             mScreenOnBlocker = new ScreenOnBlockerImpl();
-            mDisplayBlanker = new DisplayBlankerImpl();
             mWakefulness = WAKEFULNESS_AWAKE;
         }
 
@@ -458,7 +453,7 @@
         // into the activity manager to check permissions.  Unfortunately the
         // activity manager is not running when the constructor is called, so we
         // have to defer setting the screen state until this point.
-        mDisplayBlanker.unblankAllDisplays();
+        mDisplayPowerCallbacks.unblankAllDisplays();
     }
 
     void setPolicy(WindowManagerPolicy policy) {
@@ -485,20 +480,16 @@
                     mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                     mScreenOnBlocker, mPolicy);
 
-            // The display power controller runs on the power manager service's
-            // own handler thread to ensure timely operation.
-            mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
-                    mContext, mNotifier, mLightsManager,
-                    LocalServices.getService(TwilightManager.class), sensorManager,
-                    mDisplaySuspendBlocker, mDisplayBlanker,
-                    mDisplayPowerControllerCallbacks, mHandler);
-
             mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                     createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
                     mHandler);
             mSettingsObserver = new SettingsObserver(mHandler);
             mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
 
+            // Initialize display power management.
+            mDisplayManagerInternal.initPowerManagement(
+                    mDisplayPowerCallbacks, mHandler, sensorManager);
+
             // Register for broadcasts from other components of the system.
             IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_BATTERY_CHANGED);
@@ -823,7 +814,7 @@
                     return true;
 
                 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
-                    return mSystemReady && mDisplayPowerController.isProximitySensorAvailable();
+                    return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable();
 
                 default:
                     return false;
@@ -1646,7 +1637,7 @@
 
             mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
 
-            mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
+            mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
                     mRequestWaitForNegativeProximity);
             mRequestWaitForNegativeProximity = false;
 
@@ -1688,8 +1679,10 @@
         return DisplayPowerRequest.SCREEN_STATE_DIM;
     }
 
-    private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
-            new DisplayPowerController.Callbacks() {
+    private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
+            new DisplayManagerInternal.DisplayPowerCallbacks() {
+        private boolean mBlanked;
+
         @Override
         public void onStateChanged() {
             synchronized (mLock) {
@@ -1717,6 +1710,51 @@
                 updatePowerStateLocked();
             }
         }
+
+        @Override
+        public void acquireSuspendBlocker() {
+            mDisplaySuspendBlocker.acquire();
+        }
+
+        @Override
+        public void releaseSuspendBlocker() {
+            mDisplaySuspendBlocker.release();
+        }
+
+        @Override
+        public void blankAllDisplays() {
+            synchronized (this) {
+                mBlanked = true;
+                mDisplayManagerInternal.blankAllDisplaysFromPowerManager();
+                if (!mDecoupleInteractiveModeFromDisplayConfig) {
+                    setInteractiveModeLocked(false);
+                }
+                if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
+                    setAutoSuspendModeLocked(true);
+                }
+            }
+        }
+
+        @Override
+        public void unblankAllDisplays() {
+            synchronized (this) {
+                if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
+                    setAutoSuspendModeLocked(false);
+                }
+                if (!mDecoupleInteractiveModeFromDisplayConfig) {
+                    setInteractiveModeLocked(true);
+                }
+                mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();
+                mBlanked = false;
+            }
+        }
+
+        @Override
+        public String toString() {
+            synchronized (this) {
+                return "blanked=" + mBlanked;
+            }
+        }
     };
 
     private boolean shouldUseProximitySensorLocked() {
@@ -2047,7 +2085,6 @@
     private void dumpInternal(PrintWriter pw) {
         pw.println("POWER MANAGER (dumpsys power)\n");
 
-        final DisplayPowerController dpc;
         final WirelessChargerDetector wcd;
         synchronized (mLock) {
             pw.println("Power Manager State:");
@@ -2152,16 +2189,11 @@
             pw.println("Screen On Blocker: " + mScreenOnBlocker);
 
             pw.println();
-            pw.println("Display Blanker: " + mDisplayBlanker);
+            pw.println("Display Power: " + mDisplayPowerCallbacks);
 
-            dpc = mDisplayPowerController;
             wcd = mWirelessChargerDetector;
         }
 
-        if (dpc != null) {
-            dpc.dump(pw);
-        }
-
         if (wcd != null) {
             wcd.dump(pw);
         }
@@ -2499,45 +2531,6 @@
         }
     }
 
-    private final class DisplayBlankerImpl implements DisplayBlanker {
-        private boolean mBlanked;
-
-        @Override
-        public void blankAllDisplays() {
-            synchronized (this) {
-                mBlanked = true;
-                mDisplayManagerInternal.blankAllDisplaysFromPowerManager();
-                if (!mDecoupleInteractiveModeFromDisplayConfig) {
-                    setInteractiveModeLocked(false);
-                }
-                if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
-                    setAutoSuspendModeLocked(true);
-                }
-            }
-        }
-
-        @Override
-        public void unblankAllDisplays() {
-            synchronized (this) {
-                if (!mDecoupleAutoSuspendModeFromDisplayConfig) {
-                    setAutoSuspendModeLocked(false);
-                }
-                if (!mDecoupleInteractiveModeFromDisplayConfig) {
-                    setInteractiveModeLocked(true);
-                }
-                mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();
-                mBlanked = false;
-            }
-        }
-
-        @Override
-        public String toString() {
-            synchronized (this) {
-                return "blanked=" + mBlanked;
-            }
-        }
-    }
-
     private final class BinderService extends IPowerManager.Stub {
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
@@ -2874,7 +2867,7 @@
          *
          * @param adj The overridden brightness, or Float.NaN to disable the override.
          *
-         * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
+         * @see android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ
          */
         @Override // Binder call
         public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) {