Loading core/java/android/hardware/display/DisplayManagerInternal.java +164 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.hardware.display; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.view.DisplayInfo; /** Loading @@ -24,6 +27,36 @@ import android.view.DisplayInfo; * @hide Only for use within the system server. */ 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. */ Loading Loading @@ -98,6 +131,137 @@ public abstract class DisplayManagerInternal { public abstract void setDisplayHasContent(int displayId, boolean hasContent, 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 Loading services/core/java/com/android/server/power/AutomaticBrightnessController.java→services/core/java/com/android/server/display/AutomaticBrightnessController.java +6 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -25,6 +26,7 @@ import android.hardware.Sensor; 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; Loading Loading @@ -172,10 +174,10 @@ class AutomaticBrightnessController { 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; Loading @@ -198,7 +200,7 @@ class AutomaticBrightnessController { return mScreenAutoBrightness; } public void updatePowerState(DisplayPowerRequest request) { public void updatePowerState(DisplayManagerInternal.DisplayPowerRequest request) { if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment) || setLightSensorEnabled(request.wantLightSensorEnabled())) { updateAutoBrightness(false /*sendUpdate*/); Loading services/core/java/com/android/server/display/DisplayManagerService.java +29 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.internal.util.IndentingPrintWriter; 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; Loading Loading @@ -172,6 +173,9 @@ public final class DisplayManagerService extends SystemService { 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; Loading Loading @@ -936,6 +940,10 @@ public final class DisplayManagerService extends SystemService { pw.println(" " + i + ": mPid=" + callback.mPid + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); } if (mDisplayPowerController != null) { mDisplayPowerController.dump(pw); } } } Loading Loading @@ -1313,6 +1321,27 @@ public final class DisplayManagerService extends SystemService { } 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(); Loading services/core/java/com/android/server/power/DisplayPowerController.java→services/core/java/com/android/server/display/DisplayPowerController.java +56 −80 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -29,10 +29,13 @@ import android.hardware.Sensor; 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; Loading Loading @@ -80,23 +83,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // 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; Loading @@ -120,23 +106,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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; Loading Loading @@ -246,18 +224,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call /** * 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(); Loading Loading @@ -297,8 +270,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); } Loading Loading @@ -393,7 +366,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void initialize() { mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker, mPowerState = new DisplayPowerState(new ElectronBeam(), mCallbacks, mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT)); mElectronBeamOnAnimator = ObjectAnimator.ofFloat( Loading @@ -409,13 +382,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); // Initialize screen on state. // Initialize screen state for battery stats. try { if (mPowerState.isScreenOn()) { mNotifier.onScreenOn(); mBatteryStats.noteScreenOn(); } else { mNotifier.onScreenOff(); mBatteryStats.noteScreenOff(); } mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); } catch (RemoteException ex) { // same process } mNotifier.onScreenBrightness(mPowerState.getScreenBrightness()); } private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { Loading Loading @@ -653,10 +630,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void setScreenOn(boolean on) { if (mPowerState.isScreenOn() != on) { mPowerState.setScreenOn(on); try { if (on) { mNotifier.onScreenOn(); mBatteryStats.noteScreenOn(); } else { mNotifier.onScreenOff(); mBatteryStats.noteScreenOff(); } } catch (RemoteException ex) { // same process } } } Loading @@ -668,7 +649,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void animateScreenBrightness(int target, int rate) { if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { mNotifier.onScreenBrightness(target); try { mBatteryStats.noteScreenBrightness(target); } catch (RemoteException ex) { // same process } } } Loading Loading @@ -753,60 +738,60 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); Loading @@ -816,7 +801,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } 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); Loading @@ -834,7 +819,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); Loading Loading @@ -913,15 +898,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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*/); Loading services/core/java/com/android/server/power/DisplayPowerState.java→services/core/java/com/android/server/display/DisplayPowerState.java +10 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -32,8 +33,8 @@ import java.io.PrintWriter; /** * 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 Loading @@ -43,8 +44,7 @@ import java.io.PrintWriter; * 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 { Loading @@ -55,7 +55,7 @@ final class DisplayPowerState { 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; Loading @@ -72,11 +72,11 @@ final class DisplayPowerState { 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(); Loading Loading @@ -403,13 +403,13 @@ final class DisplayPowerState { + ", backlight=" + backlight); } if (onChanged && on) { mDisplayBlanker.unblankAllDisplays(); mCallbacks.unblankAllDisplays(); } if (backlightChanged) { mBacklight.setBrightness(backlight); } if (onChanged && !on) { mDisplayBlanker.blankAllDisplays(); mCallbacks.blankAllDisplays(); } } Loading Loading
core/java/android/hardware/display/DisplayManagerInternal.java +164 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.hardware.display; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.view.DisplayInfo; /** Loading @@ -24,6 +27,36 @@ import android.view.DisplayInfo; * @hide Only for use within the system server. */ 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. */ Loading Loading @@ -98,6 +131,137 @@ public abstract class DisplayManagerInternal { public abstract void setDisplayHasContent(int displayId, boolean hasContent, 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 Loading
services/core/java/com/android/server/power/AutomaticBrightnessController.java→services/core/java/com/android/server/display/AutomaticBrightnessController.java +6 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -25,6 +26,7 @@ import android.hardware.Sensor; 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; Loading Loading @@ -172,10 +174,10 @@ class AutomaticBrightnessController { 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; Loading @@ -198,7 +200,7 @@ class AutomaticBrightnessController { return mScreenAutoBrightness; } public void updatePowerState(DisplayPowerRequest request) { public void updatePowerState(DisplayManagerInternal.DisplayPowerRequest request) { if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment) || setLightSensorEnabled(request.wantLightSensorEnabled())) { updateAutoBrightness(false /*sendUpdate*/); Loading
services/core/java/com/android/server/display/DisplayManagerService.java +29 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.internal.util.IndentingPrintWriter; 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; Loading Loading @@ -172,6 +173,9 @@ public final class DisplayManagerService extends SystemService { 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; Loading Loading @@ -936,6 +940,10 @@ public final class DisplayManagerService extends SystemService { pw.println(" " + i + ": mPid=" + callback.mPid + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); } if (mDisplayPowerController != null) { mDisplayPowerController.dump(pw); } } } Loading Loading @@ -1313,6 +1321,27 @@ public final class DisplayManagerService extends SystemService { } 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(); Loading
services/core/java/com/android/server/power/DisplayPowerController.java→services/core/java/com/android/server/display/DisplayPowerController.java +56 −80 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -29,10 +29,13 @@ import android.hardware.Sensor; 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; Loading Loading @@ -80,23 +83,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // 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; Loading @@ -120,23 +106,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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; Loading Loading @@ -246,18 +224,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call /** * 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(); Loading Loading @@ -297,8 +270,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); } Loading Loading @@ -393,7 +366,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void initialize() { mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker, mPowerState = new DisplayPowerState(new ElectronBeam(), mCallbacks, mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT)); mElectronBeamOnAnimator = ObjectAnimator.ofFloat( Loading @@ -409,13 +382,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); // Initialize screen on state. // Initialize screen state for battery stats. try { if (mPowerState.isScreenOn()) { mNotifier.onScreenOn(); mBatteryStats.noteScreenOn(); } else { mNotifier.onScreenOff(); mBatteryStats.noteScreenOff(); } mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); } catch (RemoteException ex) { // same process } mNotifier.onScreenBrightness(mPowerState.getScreenBrightness()); } private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { Loading Loading @@ -653,10 +630,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void setScreenOn(boolean on) { if (mPowerState.isScreenOn() != on) { mPowerState.setScreenOn(on); try { if (on) { mNotifier.onScreenOn(); mBatteryStats.noteScreenOn(); } else { mNotifier.onScreenOff(); mBatteryStats.noteScreenOff(); } } catch (RemoteException ex) { // same process } } } Loading @@ -668,7 +649,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void animateScreenBrightness(int target, int rate) { if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { mNotifier.onScreenBrightness(target); try { mBatteryStats.noteScreenBrightness(target); } catch (RemoteException ex) { // same process } } } Loading Loading @@ -753,60 +738,60 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); Loading @@ -816,7 +801,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } 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); Loading @@ -834,7 +819,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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); Loading Loading @@ -913,15 +898,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call 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*/); Loading
services/core/java/com/android/server/power/DisplayPowerState.java→services/core/java/com/android/server/display/DisplayPowerState.java +10 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -32,8 +33,8 @@ import java.io.PrintWriter; /** * 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 Loading @@ -43,8 +44,7 @@ import java.io.PrintWriter; * 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 { Loading @@ -55,7 +55,7 @@ final class DisplayPowerState { 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; Loading @@ -72,11 +72,11 @@ final class DisplayPowerState { 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(); Loading Loading @@ -403,13 +403,13 @@ final class DisplayPowerState { + ", backlight=" + backlight); } if (onChanged && on) { mDisplayBlanker.unblankAllDisplays(); mCallbacks.unblankAllDisplays(); } if (backlightChanged) { mBacklight.setBrightness(backlight); } if (onChanged && !on) { mDisplayBlanker.blankAllDisplays(); mCallbacks.blankAllDisplays(); } } Loading