summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/power/DisplayPowerController.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/power/DisplayPowerController.java')
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java83
1 files changed, 81 insertions, 2 deletions
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index e5edb4012de2..80ad6121202d 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -17,6 +17,8 @@
package com.android.server.power;
import com.android.server.LightsService;
+import com.android.server.TwilightService;
+import com.android.server.TwilightService.TwilightState;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -88,6 +90,22 @@ final class DisplayPowerController {
// auto-brightness adjustment setting.
private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
+ // 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 = true;
+
+ // 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 = 300;
private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 600;
@@ -148,6 +166,9 @@ final class DisplayPowerController {
// The lights service.
private final LightsService mLights;
+ // The twilight service.
+ private final TwilightService mTwilight;
+
// The sensor manager.
private final SensorManager mSensorManager;
@@ -291,11 +312,14 @@ final class DisplayPowerController {
private ObjectAnimator mElectronBeamOffAnimator;
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
+ // Twilight changed. We might recalculate auto-brightness values.
+ private boolean mTwilightChanged;
+
/**
* Creates the display power controller.
*/
public DisplayPowerController(Looper looper, Context context, Notifier notifier,
- LightsService lights, SuspendBlocker suspendBlocker,
+ LightsService lights, TwilightService twilight, SuspendBlocker suspendBlocker,
Callbacks callbacks, Handler callbackHandler) {
mHandler = new DisplayControllerHandler(looper);
mNotifier = notifier;
@@ -304,6 +328,7 @@ final class DisplayPowerController {
mCallbackHandler = callbackHandler;
mLights = lights;
+ mTwilight = twilight;
mSensorManager = new SystemSensorManager(mHandler.getLooper());
final Resources resources = context.getResources();
@@ -344,6 +369,10 @@ final class DisplayPowerController {
&& !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
+
+ if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) {
+ mTwilight.registerListener(mTwilightListener, mHandler);
+ }
}
private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
@@ -486,7 +515,8 @@ final class DisplayPowerController {
// Update the power state request.
final boolean mustNotify;
boolean mustInitialize = false;
- boolean updateAutoBrightness = false;
+ boolean updateAutoBrightness = mTwilightChanged;
+ mTwilightChanged = false;
synchronized (mLock) {
mPendingUpdatePowerStateLocked = false;
@@ -863,6 +893,22 @@ final class DisplayPowerController {
}
}
+ if (USE_TWILIGHT_ADJUSTMENT) {
+ TwilightState state = mTwilight.getCurrentState();
+ if (state != null && state.isNight()) {
+ final long now = System.currentTimeMillis();
+ final float earlyGamma =
+ getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
+ final float lateGamma =
+ getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
+ gamma *= earlyGamma * lateGamma;
+ if (DEBUG) {
+ Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
+ + ", lateGamma=" + lateGamma);
+ }
+ }
+ }
+
if (gamma != 1.0f) {
final float in = value;
value = FloatMath.pow(value, gamma);
@@ -889,6 +935,29 @@ final class DisplayPowerController {
}
}
+ private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
+ if (lastSunset < 0 || nextSunrise < 0
+ || now < lastSunset || now > nextSunrise) {
+ return 1.0f;
+ }
+
+ if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
+ return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+ (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
+ }
+
+ if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
+ return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+ (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
+ }
+
+ return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
+ }
+
+ private static float lerp(float x, float y, float alpha) {
+ return x + (y - x) * alpha;
+ }
+
private void sendOnStateChanged() {
mCallbackHandler.post(mOnStateChangedRunnable);
}
@@ -995,6 +1064,7 @@ final class DisplayPowerController {
pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness);
pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
+ pw.println(" mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
if (mElectronBeamOnAnimator != null) {
pw.println(" mElectronBeamOnAnimator.isStarted()=" +
@@ -1095,4 +1165,13 @@ final class DisplayPowerController {
// Not used.
}
};
+
+ private final TwilightService.TwilightListener mTwilightListener =
+ new TwilightService.TwilightListener() {
+ @Override
+ public void onTwilightStateChanged() {
+ mTwilightChanged = true;
+ updatePowerState();
+ }
+ };
}