Add a mechanism to adjust auto-brightness at night.
Uses the twilight service to determine the hours of sunrise and sunset. Shortly after sunset or before sunrise gradually start to apply a gamma correction factor to the auto-brightness calculations to make the screen a little dimmer at night. The effect is relatively small and is mostly noticeable in dark rooms. This is just a first pass at the algorithm, we can tweak the adjustment later to ensure that it has even less impact in moderate or bright environments. Change-Id: Idf89022a5d0bb52975e04779352d53fa63371178
This commit is contained in:
@@ -741,7 +741,12 @@ class ServerThread extends Thread {
|
||||
w.getDefaultDisplay().getMetrics(metrics);
|
||||
context.getResources().updateConfiguration(config, metrics);
|
||||
|
||||
power.systemReady();
|
||||
try {
|
||||
power.systemReady(twilight);
|
||||
} catch (Throwable e) {
|
||||
reportWtf("making Power Manager Service ready", e);
|
||||
}
|
||||
|
||||
try {
|
||||
pm.systemReady();
|
||||
} catch (Throwable e) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.android.internal.app.IBatteryStats;
|
||||
import com.android.server.BatteryService;
|
||||
import com.android.server.EventLogTags;
|
||||
import com.android.server.LightsService;
|
||||
import com.android.server.TwilightService;
|
||||
import com.android.server.Watchdog;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.display.DisplayManagerService;
|
||||
@@ -318,7 +319,7 @@ public final class PowerManagerService extends IPowerManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
public void systemReady() {
|
||||
public void systemReady(TwilightService twilight) {
|
||||
synchronized (mLock) {
|
||||
mSystemReady = true;
|
||||
|
||||
@@ -331,7 +332,7 @@ public final class PowerManagerService extends IPowerManager.Stub
|
||||
createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
|
||||
mPolicy, mScreenOnListener);
|
||||
mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
|
||||
mContext, mNotifier, mLightsService,
|
||||
mContext, mNotifier, mLightsService, twilight,
|
||||
createSuspendBlockerLocked("PowerManagerService.Display"),
|
||||
mDisplayPowerControllerCallbacks, mHandler);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user