19630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/*
29630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Copyright (C) 2012 The Android Open Source Project
39630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
49630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
59630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * you may not use this file except in compliance with the License.
69630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * You may obtain a copy of the License at
79630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
89630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
99630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Unless required by applicable law or agreed to in writing, software
119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * See the License for the specific language governing permissions and
149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * limitations under the License.
159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */
169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownpackage com.android.server.power;
189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport com.android.server.LightsService;
20aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brownimport com.android.server.TwilightService;
21aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brownimport com.android.server.TwilightService.TwilightState;
229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.animation.Animator;
249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.animation.ObjectAnimator;
259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.content.Context;
269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.content.res.Resources;
279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.hardware.Sensor;
289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.hardware.SensorEvent;
299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.hardware.SensorEventListener;
309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.hardware.SensorManager;
319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.hardware.SystemSensorManager;
3298365d7663cbd82979a5700faf0050220b01084dJeff Brownimport android.hardware.display.DisplayManager;
339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Handler;
349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Looper;
359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Message;
36330560f53bccd06be805fee1b7988162119d1295Jeff Brownimport android.os.PowerManager;
379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.SystemClock;
38330560f53bccd06be805fee1b7988162119d1295Jeff Brownimport android.text.format.DateUtils;
39330560f53bccd06be805fee1b7988162119d1295Jeff Brownimport android.util.FloatMath;
409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.Slog;
411a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brownimport android.util.Spline;
429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.TimeUtils;
4398365d7663cbd82979a5700faf0050220b01084dJeff Brownimport android.view.Display;
449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport java.io.PrintWriter;
469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/**
489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Controls the power state of the display.
499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Handles the proximity sensor, light sensor, and animations between states
519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * including the screen off animation.
529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This component acts independently of the rest of the power manager service.
549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * In particular, it does not share any state and it only communicates
559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * via asynchronous callbacks to inform the power manager that something has
569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * changed.
579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Everything this class does internally is serialized on its handler although
599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * it may be accessed by other threads from the outside.
609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Note that the power manager service guarantees that it will hold a suspend
629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * blocker as long as the display is not ready.  So most of the work done here
639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * does not need to worry about holding a suspend blocker unless it happens
649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * independently of the display ready signal.
659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown *
669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * For debugging, you can make the electron beam and brightness animations run
679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * slower by changing the "animator duration scale" option in Development Settings.
689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */
699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownfinal class DisplayPowerController {
709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final String TAG = "DisplayPowerController";
719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static boolean DEBUG = false;
739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
7613c589b66c47aa4d988eecce9a12c39d580939c9Jeff Brown    // If true, uses the electron beam on animation.
7713c589b66c47aa4d988eecce9a12c39d580939c9Jeff Brown    // We might want to turn this off if we cannot get a guarantee that the screen
7813c589b66c47aa4d988eecce9a12c39d580939c9Jeff Brown    // actually turns on and starts showing new content after the call to set the
795356c7dc72e80bbadd0ffbc69cfe3ea333280785Jeff Brown    // screen state returns.  Playing the animation can also be somewhat slow.
805356c7dc72e80bbadd0ffbc69cfe3ea333280785Jeff Brown    private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
8113c589b66c47aa4d988eecce9a12c39d580939c9Jeff Brown
82330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // If true, enables the use of the screen auto-brightness adjustment setting.
83631938f26dbc89e7e9530bb85d9f37706dba59f3Jeff Brown    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
84631938f26dbc89e7e9530bb85d9f37706dba59f3Jeff Brown            PowerManager.useScreenAutoBrightnessAdjustmentFeature();
85330560f53bccd06be805fee1b7988162119d1295Jeff Brown
86330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // The maximum range of gamma adjustment possible using the screen
87330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // auto-brightness adjustment setting.
88330560f53bccd06be805fee1b7988162119d1295Jeff Brown    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
89330560f53bccd06be805fee1b7988162119d1295Jeff Brown
90b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    // The minimum reduction in brightness when dimmed.
91b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
92b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
93aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // If true, enables the use of the current time as an auto-brightness adjustment.
94aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // The basic idea here is to expand the dynamic range of auto-brightness
95aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // when it is especially dark outside.  The light sensor tends to perform
96aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // poorly at low light levels so we compensate for it by making an
97aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // assumption about the environment.
98db21284a7fb081065d26137891594bd8495b116fJeff Brown    private static final boolean USE_TWILIGHT_ADJUSTMENT =
99db21284a7fb081065d26137891594bd8495b116fJeff Brown            PowerManager.useTwilightAdjustmentFeature();
100aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
101aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // Specifies the maximum magnitude of the time of day adjustment.
102aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
103aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
104aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // The amount of time after or before sunrise over which to start adjusting
105aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // the gamma.  We want the change to happen gradually so that it is below the
106aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // threshold of perceptibility and so that the adjustment has maximum effect
107aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // well after dusk.
108aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
109aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
11000a8f4ff627584f4d9a8ae0cd83f87786005e16dJeff Brown    private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250;
1113c584f20ac8fe9378c094ad3b63936bca35954baJeff Brown    private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400;
1129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int MSG_UPDATE_POWER_STATE = 1;
1149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
1159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
1169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int PROXIMITY_UNKNOWN = -1;
1189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int PROXIMITY_NEGATIVE = 0;
1199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int PROXIMITY_POSITIVE = 1;
1209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12193cbbb25a56356cd36523809783a277fe92e312eJeff Brown    // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
12293cbbb25a56356cd36523809783a277fe92e312eJeff Brown    private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
12393cbbb25a56356cd36523809783a277fe92e312eJeff Brown    private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500;
1249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Trigger proximity if distance is less than 5 cm.
1269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
1279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
128e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // Light sensor event rate in milliseconds.
129e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
130e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
131e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // A rate for generating synthetic light sensor events in the case where the light
132e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // sensor hasn't reported any new data in a while and we need it to update the
133e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // debounce filter.  We only synthesize light sensor measurements when needed.
134e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS =
135e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            LIGHT_SENSOR_RATE_MILLIS * 2;
1369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Brightness animation ramp rate in brightness units per second.
1389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
139e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
1409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1414f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // IIR filter time constants in milliseconds for computing two moving averages of
1424f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // the light samples.  One is a long-term average and the other is a short-term average.
1434f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // We can use these filters to assess trends in ambient brightness.
1444f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The short term average gives us a filtered but relatively low latency measurement.
1454f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The long term average informs us about the overall trend.
1464f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000;
147e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000;
14806565b64de1953fc9534f789b2e8b8fd70758979Jeff Brown
14906565b64de1953fc9534f789b2e8b8fd70758979Jeff Brown    // Stability requirements in milliseconds for accepting a new brightness
15006565b64de1953fc9534f789b2e8b8fd70758979Jeff Brown    // level.  This is used for debouncing the light sensor.  Different constants
1514f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // are used to debounce the light sensor when adapting to brighter or darker environments.
15206565b64de1953fc9534f789b2e8b8fd70758979Jeff Brown    // This parameter controls how quickly brightness changes occur in response to
153e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // an observed change in light level that exceeds the hysteresis threshold.
154e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
155e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
1564f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown
1574f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // Hysteresis constraints for brightening or darkening.
1584f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The recent lux must have changed by at least this fraction relative to the
1594f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // current ambient lux before a change will be considered.
1604f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
1614f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
1629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Object mLock = new Object();
1649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Notifier for sending asynchronous notifications.
1669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Notifier mNotifier;
1679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1689e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    // The display blanker.
1699e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private final DisplayBlanker mDisplayBlanker;
1709e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
1719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Our handler.
1729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final DisplayControllerHandler mHandler;
1739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Asynchronous callbacks into the power manager service.
1759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Only invoked from the handler thread while no locks are held.
1769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Callbacks mCallbacks;
1779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private Handler mCallbackHandler;
1789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The lights service.
1809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final LightsService mLights;
1819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
182aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // The twilight service.
183aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private final TwilightService mTwilight;
184aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
185bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // The display manager.
186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final DisplayManager mDisplayManager;
187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The sensor manager.
1899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final SensorManager mSensorManager;
1909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The proximity sensor, or null if not available or needed.
1929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private Sensor mProximitySensor;
1939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The light sensor, or null if not available or needed.
1959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private Sensor mLightSensor;
1969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The dim screen brightness.
1989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final int mScreenBrightnessDimConfig;
1999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
200b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    // The minimum allowed brightness.
201b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private final int mScreenBrightnessRangeMinimum;
202b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
203b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    // The maximum allowed brightness.
204b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private final int mScreenBrightnessRangeMaximum;
205b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
206330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // True if auto-brightness should be used.
2079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mUseSoftwareAutoBrightnessConfig;
208330560f53bccd06be805fee1b7988162119d1295Jeff Brown
209330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // The auto-brightness spline adjustment.
210330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // The brightness values have been scaled to a range of 0..1.
2111a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown    private Spline mScreenAutoBrightnessSpline;
2129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Amount of time to delay auto-brightness after screen on while waiting for
2149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // the light sensor to warm-up in milliseconds.
2159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // May be 0 if no warm-up is required.
2169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private int mLightSensorWarmUpTimeConfig;
2179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
218252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown    // True if we should fade the screen while turning it off, false if we should play
219252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown    // a stylish electron beam animation instead.
220252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown    private boolean mElectronBeamFadesConfig;
221a52772ff26e41dbb242a78a1f30619e23fb13dd7Jeff Brown
2229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The pending power request.
2239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Initially null until the first call to requestPowerState.
2249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Guarded by mLock.
2259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private DisplayPowerRequest mPendingRequestLocked;
2269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // True if a request has been made to wait for the proximity sensor to go negative.
2289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Guarded by mLock.
2299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mPendingWaitForNegativeProximityLocked;
2309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // True if the pending power request or wait for negative proximity flag
2329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // has been changed since the last update occurred.
2339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Guarded by mLock.
2349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mPendingRequestChangedLocked;
2359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Set to true when the important parts of the pending power request have been applied.
2379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The important parts are mainly the screen state.  Brightness changes may occur
2389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // concurrently.
2399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Guarded by mLock.
2409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mDisplayReadyLocked;
2419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Set to true if a power state update is required.
2439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Guarded by mLock.
2449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mPendingUpdatePowerStateLocked;
2459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /* The following state must only be accessed by the handler thread. */
2479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The currently requested power state.
2499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The power controller will progressively update its internal state to match
2509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // the requested power state.  Initially null until the first update.
2519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private DisplayPowerRequest mPowerRequest;
2529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The current power state.
2549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Must only be accessed on the handler thread.
2559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private DisplayPowerState mPowerState;
2569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // True if the device should wait for negative proximity sensor before
2589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // waking up the screen.  This is set to false as soon as a negative
2599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // proximity sensor measurement is observed or when the device is forced to
2609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // go to sleep by the user.  While true, the screen remains off.
2619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mWaitingForNegativeProximity;
2629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The actual proximity sensor threshold value.
2649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private float mProximityThreshold;
2659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Set to true if the proximity sensor listener has been registered
2679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // with the sensor manager.
2689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mProximitySensorEnabled;
2699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The debounced proximity sensor state.
2719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private int mProximity = PROXIMITY_UNKNOWN;
2729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The raw non-debounced proximity sensor state.
2749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private int mPendingProximity = PROXIMITY_UNKNOWN;
2759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private long mPendingProximityDebounceTime;
2769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // True if the screen was turned off because of the proximity sensor.
2789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // When the screen turns on again, we report user activity to the power manager.
2799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mScreenOffBecauseOfProximity;
2809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2818b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    // True if the screen on is being blocked.
2828b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    private boolean mScreenOnWasBlocked;
2838b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown
2848b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    // The elapsed real time when the screen on was blocked.
2858b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    private long mScreenOnBlockStartRealTime;
2868b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown
2879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Set to true if the light sensor is enabled.
2889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mLightSensorEnabled;
2899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The time when the light sensor was enabled.
2919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private long mLightSensorEnableTime;
2929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2934f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The currently accepted nominal ambient light level.
2944f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private float mAmbientLux;
2959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2964f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // True if mAmbientLux holds a valid value.
2974f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private boolean mAmbientLuxValid;
2989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The most recent light sample.
3004f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private float mLastObservedLux;
3019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The time of the most light recent sample.
3034f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private long mLastObservedLuxTime;
3049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3054f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The number of light samples collected since the light sensor was enabled.
3064f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private int mRecentLightSamples;
30706565b64de1953fc9534f789b2e8b8fd70758979Jeff Brown
3084f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    // The long-term and short-term filtered light measurements.
3094f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private float mRecentShortTermAverageLux;
3104f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private float mRecentLongTermAverageLux;
3119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
312e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // The direction in which the average lux is moving relative to the current ambient lux.
313e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    //    0 if not changing or within hysteresis threshold.
314e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    //    1 if brightening beyond hysteresis threshold.
315e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    //   -1 if darkening beyond hysteresis threshold.
316e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private int mDebounceLuxDirection;
317e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
318e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    // The time when the average lux last changed direction.
319e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private long mDebounceLuxTime;
320e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
3219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // The screen brightness level that has been chosen by the auto-brightness
3229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // algorithm.  The actual brightness should ramp towards this value.
3239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // We preserve this value even when we stop using the light sensor so
3249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // that we can quickly revert to the previous auto-brightness level
3259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // while the light sensor warms up.
3269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Use -1 if there is no current auto-brightness value available.
3279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private int mScreenAutoBrightness = -1;
3289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
329330560f53bccd06be805fee1b7988162119d1295Jeff Brown    // The last screen auto-brightness gamma.  (For printing in dump() only.)
330330560f53bccd06be805fee1b7988162119d1295Jeff Brown    private float mLastScreenAutoBrightnessGamma = 1.0f;
331330560f53bccd06be805fee1b7988162119d1295Jeff Brown
3329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // True if the screen auto-brightness value is actually being used to
3339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // set the display brightness.
3349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private boolean mUsingScreenAutoBrightness;
3359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    // Animators.
3379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private ObjectAnimator mElectronBeamOnAnimator;
3389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private ObjectAnimator mElectronBeamOffAnimator;
3399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
3409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
341aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    // Twilight changed.  We might recalculate auto-brightness values.
342aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private boolean mTwilightChanged;
343aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
3449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
3459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Creates the display power controller.
3469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
3479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public DisplayPowerController(Looper looper, Context context, Notifier notifier,
34832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            LightsService lights, TwilightService twilight,
3499e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            DisplayBlanker displayBlanker,
3509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            Callbacks callbacks, Handler callbackHandler) {
3519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mHandler = new DisplayControllerHandler(looper);
3529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mNotifier = notifier;
3539e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        mDisplayBlanker = displayBlanker;
3549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mCallbacks = callbacks;
3559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mCallbackHandler = callbackHandler;
3569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mLights = lights;
358aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        mTwilight = twilight;
3599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mSensorManager = new SystemSensorManager(mHandler.getLooper());
360bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
3619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        final Resources resources = context.getResources();
363b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
364b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
365b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                com.android.internal.R.integer.config_screenBrightnessDim));
366b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
367b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        int screenBrightnessMinimum = Math.min(resources.getInteger(
368b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                com.android.internal.R.integer.config_screenBrightnessSettingMinimum),
369b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                mScreenBrightnessDimConfig);
370b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
3719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
3729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                com.android.internal.R.bool.config_automatic_brightness_available);
3739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mUseSoftwareAutoBrightnessConfig) {
3741a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            int[] lux = resources.getIntArray(
3759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    com.android.internal.R.array.config_autoBrightnessLevels);
3761a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            int[] screenBrightness = resources.getIntArray(
3779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
3781a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown
3791a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
3801a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            if (mScreenAutoBrightnessSpline == null) {
3819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                Slog.e(TAG, "Error in config.xml.  config_autoBrightnessLcdBacklightValues "
3821a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                        + "(size " + screenBrightness.length + ") "
3831a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                        + "must be monotic and have exactly one more entry than "
3841a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                        + "config_autoBrightnessLevels (size " + lux.length + ") "
3851a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                        + "which must be strictly increasing.  "
3869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        + "Auto-brightness will be disabled.");
3879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mUseSoftwareAutoBrightnessConfig = false;
388b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            } else {
389b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                if (screenBrightness[0] < screenBrightnessMinimum) {
390b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                    screenBrightnessMinimum = screenBrightness[0];
391b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                }
3929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
3939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mLightSensorWarmUpTimeConfig = resources.getInteger(
3959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    com.android.internal.R.integer.config_lightSensorWarmupTime);
3969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
3979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
398b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum);
399b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
400b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
401252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown        mElectronBeamFadesConfig = resources.getBoolean(
402a52772ff26e41dbb242a78a1f30619e23fb13dd7Jeff Brown                com.android.internal.R.bool.config_animateScreenLights);
403a52772ff26e41dbb242a78a1f30619e23fb13dd7Jeff Brown
4049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
4059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
4069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mProximitySensor != null) {
4079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
4089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        TYPICAL_PROXIMITY_THRESHOLD);
4099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
4109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
4119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mUseSoftwareAutoBrightnessConfig
4139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
4149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
4159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
416aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
417aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) {
418aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            mTwilight.registerListener(mTwilightListener, mHandler);
419aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
4209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
4219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4221a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown    private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
4231a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown        try {
4241a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            final int n = brightness.length;
4251a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            float[] x = new float[n];
4261a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            float[] y = new float[n];
427b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            y[0] = normalizeAbsoluteBrightness(brightness[0]);
4281a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            for (int i = 1; i < n; i++) {
4291a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                x[i] = lux[i - 1];
430b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                y[i] = normalizeAbsoluteBrightness(brightness[i]);
4311a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            }
4321a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown
4331a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            Spline spline = Spline.createMonotoneCubicSpline(x, y);
434b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            if (DEBUG) {
4351a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                Slog.d(TAG, "Auto-brightness spline: " + spline);
4361a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
4371a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                    Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
4381a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                }
4391a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            }
4401a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            return spline;
4411a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown        } catch (IllegalArgumentException ex) {
4421a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            Slog.e(TAG, "Could not create auto-brightness spline.", ex);
4431a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown            return null;
4441a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown        }
4451a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown    }
4461a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown
4479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
4489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Returns true if the proximity sensor screen-off function is available.
4499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
4509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public boolean isProximitySensorAvailable() {
4519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        return mProximitySensor != null;
4529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
4539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
4559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Requests a new power state.
4569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * The controller makes a copy of the provided object and then
4579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * begins adjusting the power state to match what was requested.
4589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     *
4599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * @param request The requested power state.
4609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * @param waitForNegativeProximity If true, issues a request to wait for
4619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * negative proximity before turning the screen back on, assuming the screen
4629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * was turned off by the proximity sensor.
4639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * @return True if display is ready, false if there are important changes that must
4649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * be made asynchronously (such as turning the screen on), in which case the caller
4659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try
4669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * the request again later until the state converges.
4679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
4689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public boolean requestPowerState(DisplayPowerRequest request,
4699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            boolean waitForNegativeProximity) {
4709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (DEBUG) {
4719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            Slog.d(TAG, "requestPowerState: "
4729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
4739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
4749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        synchronized (mLock) {
4769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            boolean changed = false;
4779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (waitForNegativeProximity
4799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    && !mPendingWaitForNegativeProximityLocked) {
4809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingWaitForNegativeProximityLocked = true;
4819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                changed = true;
4829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
4839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mPendingRequestLocked == null) {
4859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingRequestLocked = new DisplayPowerRequest(request);
4869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                changed = true;
4879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else if (!mPendingRequestLocked.equals(request)) {
4889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingRequestLocked.copyFrom(request);
4899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                changed = true;
4909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
4919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (changed) {
4939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mDisplayReadyLocked = false;
4949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
4959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
4969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (changed && !mPendingRequestChangedLocked) {
4979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingRequestChangedLocked = true;
4989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                sendUpdatePowerStateLocked();
4999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
5009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return mDisplayReadyLocked;
5029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
5049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void sendUpdatePowerState() {
5069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        synchronized (mLock) {
5079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            sendUpdatePowerStateLocked();
5089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
5109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void sendUpdatePowerStateLocked() {
5129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (!mPendingUpdatePowerStateLocked) {
5139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mPendingUpdatePowerStateLocked = true;
5149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
5159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            msg.setAsynchronous(true);
5169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mHandler.sendMessage(msg);
5179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
5199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void initialize() {
521bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
522a52772ff26e41dbb242a78a1f30619e23fb13dd7Jeff Brown        mPowerState = new DisplayPowerState(
52332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                new ElectronBeam(display), mDisplayBlanker,
52432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT));
5259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
5279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f);
5289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS);
5299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOnAnimator.addListener(mAnimatorListener);
5309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOffAnimator = ObjectAnimator.ofFloat(
5329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f);
5339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS);
5349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mElectronBeamOffAnimator.addListener(mAnimatorListener);
5359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
5379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
5389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
5399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
5419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
5429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAnimationStart(Animator animation) {
5439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
5459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAnimationEnd(Animator animation) {
5469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            sendUpdatePowerState();
5479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
5499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAnimationRepeat(Animator animation) {
5509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
5529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAnimationCancel(Animator animation) {
5539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
5559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void updatePowerState() {
5579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Update the power state request.
5589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        final boolean mustNotify;
5599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        boolean mustInitialize = false;
560aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        boolean updateAutoBrightness = mTwilightChanged;
561e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        boolean wasDim = false;
562aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        mTwilightChanged = false;
563330560f53bccd06be805fee1b7988162119d1295Jeff Brown
5649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        synchronized (mLock) {
5659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mPendingUpdatePowerStateLocked = false;
5669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mPendingRequestLocked == null) {
5679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return; // wait until first actual power request
5689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
5699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mPowerRequest == null) {
5719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
5729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
5736307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                mPendingWaitForNegativeProximityLocked = false;
5749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingRequestChangedLocked = false;
5759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mustInitialize = true;
5769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else if (mPendingRequestChangedLocked) {
577330560f53bccd06be805fee1b7988162119d1295Jeff Brown                if (mPowerRequest.screenAutoBrightnessAdjustment
578330560f53bccd06be805fee1b7988162119d1295Jeff Brown                        != mPendingRequestLocked.screenAutoBrightnessAdjustment) {
579330560f53bccd06be805fee1b7988162119d1295Jeff Brown                    updateAutoBrightness = true;
580330560f53bccd06be805fee1b7988162119d1295Jeff Brown                }
581e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                wasDim = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM);
5829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPowerRequest.copyFrom(mPendingRequestLocked);
5839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
5846307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                mPendingWaitForNegativeProximityLocked = false;
5859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingRequestChangedLocked = false;
5869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mDisplayReadyLocked = false;
5879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
5889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mustNotify = !mDisplayReadyLocked;
5909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Initialize things the first time the power state is changed.
5939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mustInitialize) {
5949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            initialize();
5959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
5969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5976307a150d374cec7b20f80a68800bbf69f495839Jeff Brown        // Apply the proximity sensor.
5989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mProximitySensor != null) {
5996307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            if (mPowerRequest.useProximitySensor
6006307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
6016307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                setProximitySensorEnabled(true);
6026307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                if (!mScreenOffBecauseOfProximity
6036307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                        && mProximity == PROXIMITY_POSITIVE) {
6046307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    mScreenOffBecauseOfProximity = true;
60593cbbb25a56356cd36523809783a277fe92e312eJeff Brown                    sendOnProximityPositive();
6066307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    setScreenOn(false);
6076307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                }
6086307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            } else if (mWaitingForNegativeProximity
6096307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    && mScreenOffBecauseOfProximity
6106307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    && mProximity == PROXIMITY_POSITIVE
6116307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
6126307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                setProximitySensorEnabled(true);
6136307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            } else {
6146307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                setProximitySensorEnabled(false);
6156307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                mWaitingForNegativeProximity = false;
6166307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            }
6176307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            if (mScreenOffBecauseOfProximity
6186307a150d374cec7b20f80a68800bbf69f495839Jeff Brown                    && mProximity != PROXIMITY_POSITIVE) {
6199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mScreenOffBecauseOfProximity = false;
6209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                sendOnProximityNegative();
6219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
6226307a150d374cec7b20f80a68800bbf69f495839Jeff Brown        } else {
6236307a150d374cec7b20f80a68800bbf69f495839Jeff Brown            mWaitingForNegativeProximity = false;
6249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
6259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
6269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Turn on the light sensor if needed.
6279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mLightSensor != null) {
6289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            setLightSensorEnabled(mPowerRequest.useAutoBrightness
629330560f53bccd06be805fee1b7988162119d1295Jeff Brown                    && wantScreenOn(mPowerRequest.screenState), updateAutoBrightness);
6309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
6319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
6329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Set the screen brightness.
633b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        if (wantScreenOn(mPowerRequest.screenState)) {
634b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            int target;
635b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            boolean slow;
6369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
6379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Use current auto-brightness value.
638b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                target = mScreenAutoBrightness;
639b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                slow = mUsingScreenAutoBrightness;
6409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mUsingScreenAutoBrightness = true;
6419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else {
6429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Light sensor is disabled or not ready yet.
6439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Use the current brightness setting from the request, which is expected
6449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // provide a nominal default value for the case where auto-brightness
6459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // is not ready yet.
646b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                target = mPowerRequest.screenBrightness;
647b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                slow = false;
6489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mUsingScreenAutoBrightness = false;
6499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
650b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
6515244c93176497f7c151f85a46e46b534379603bcJeff Brown                // Dim quickly by at least some minimum amount.
652b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
653b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                        mScreenBrightnessDimConfig);
6545244c93176497f7c151f85a46e46b534379603bcJeff Brown                slow = false;
655e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            } else if (wasDim) {
656e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                // Brighten quickly.
657b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                slow = false;
658b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            }
659b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            animateScreenBrightness(clampScreenBrightness(target),
660b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown                    slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
6619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        } else {
6629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            // Screen is off.  Don't bother changing the brightness.
6639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mUsingScreenAutoBrightness = false;
6649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
6659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
6669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Animate the screen on or off.
6679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (!mScreenOffBecauseOfProximity) {
6689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (wantScreenOn(mPowerRequest.screenState)) {
6699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Want screen on.
6709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Wait for previous off animation to complete beforehand.
6719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // It is relatively short but if we cancel it and switch to the
6729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // on animation immediately then the results are pretty ugly.
6739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                if (!mElectronBeamOffAnimator.isStarted()) {
6748b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                    // Turn the screen on.  The contents of the screen may not yet
6758b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                    // be visible if the electron beam has not been dismissed because
6768b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                    // its last frame of animation is solid black.
6778b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                    setScreenOn(true);
6788b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown
6798b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                    if (mPowerRequest.blockScreenOn
6808b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                            && mPowerState.getElectronBeamLevel() == 0.0f) {
6818b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                        blockScreenOn();
68213c589b66c47aa4d988eecce9a12c39d580939c9Jeff Brown                    } else {
6838b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                        unblockScreenOn();
684c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                        if (USE_ELECTRON_BEAM_ON_ANIMATION) {
685c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                            if (!mElectronBeamOnAnimator.isStarted()) {
686c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                if (mPowerState.getElectronBeamLevel() == 1.0f) {
687c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                    mPowerState.dismissElectronBeam();
6888b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                                } else if (mPowerState.prepareElectronBeam(
689252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown                                        mElectronBeamFadesConfig ?
690252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown                                                ElectronBeam.MODE_FADE :
6918b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                                                        ElectronBeam.MODE_WARM_UP)) {
692c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                    mElectronBeamOnAnimator.start();
693c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                } else {
694c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                    mElectronBeamOnAnimator.end();
695c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                                }
696c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                            }
697c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                        } else {
698c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                            mPowerState.setElectronBeamLevel(1.0f);
699c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                            mPowerState.dismissElectronBeam();
700c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                        }
701c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                    }
7029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                }
7039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else {
7049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Want screen off.
7059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                // Wait for previous on animation to complete beforehand.
7069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                if (!mElectronBeamOnAnimator.isStarted()) {
7079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    if (!mElectronBeamOffAnimator.isStarted()) {
7089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        if (mPowerState.getElectronBeamLevel() == 0.0f) {
7099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                            setScreenOn(false);
7108b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                        } else if (mPowerState.prepareElectronBeam(
711252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown                                mElectronBeamFadesConfig ?
712252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown                                        ElectronBeam.MODE_FADE :
7138b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                                                ElectronBeam.MODE_COOL_DOWN)
7149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                                && mPowerState.isScreenOn()) {
7159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                            mElectronBeamOffAnimator.start();
7169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        } else {
7179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                            mElectronBeamOffAnimator.end();
7189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        }
7199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    }
7209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                }
7219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
7229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
7239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
7249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Report whether the display is ready for use.
7259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // We mostly care about the screen state here, ignoring brightness changes
7269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // which will be handled asynchronously.
7279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mustNotify
7288b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                && !mScreenOnWasBlocked
7299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                && !mElectronBeamOnAnimator.isStarted()
7309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                && !mElectronBeamOffAnimator.isStarted()
7319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                && mPowerState.waitUntilClean(mCleanListener)) {
7329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            synchronized (mLock) {
7339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                if (!mPendingRequestChangedLocked) {
7349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    mDisplayReadyLocked = true;
735c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown
736c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                    if (DEBUG) {
737c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                        Slog.d(TAG, "Display ready!");
738c38c9be031ddad5cf551b55458889f11e01dc5b2Jeff Brown                    }
7399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                }
7409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
7419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            sendOnStateChanged();
7429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
7439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
7449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
7458b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    private void blockScreenOn() {
7468b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown        if (!mScreenOnWasBlocked) {
7478b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            mScreenOnWasBlocked = true;
7488b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            if (DEBUG) {
7498b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                Slog.d(TAG, "Blocked screen on.");
7508b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
7518b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            }
7528b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown        }
7538b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    }
7548b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown
7558b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    private void unblockScreenOn() {
7568b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown        if (mScreenOnWasBlocked) {
7578b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            mScreenOnWasBlocked = false;
7588b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            if (DEBUG) {
7598b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                Slog.d(TAG, "Unblocked screen on after " +
7608b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown                        (SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms");
7618b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown            }
7628b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown        }
7638b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown    }
7648b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown
7659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void setScreenOn(boolean on) {
7669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (!mPowerState.isScreenOn() == on) {
7679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mPowerState.setScreenOn(on);
7689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (on) {
7699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mNotifier.onScreenOn();
7709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else {
7719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mNotifier.onScreenOff();
7729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
7739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
7749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
7759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
776330560f53bccd06be805fee1b7988162119d1295Jeff Brown    private int clampScreenBrightness(int value) {
777b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
778b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    }
779b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
780b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private static int clampAbsoluteBrightness(int value) {
781b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
782b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    }
783b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
784b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private static int clamp(int value, int min, int max) {
785b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        if (value <= min) {
786b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            return min;
787b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        }
788b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        if (value >= max) {
789b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown            return max;
790b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        }
791b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        return value;
792b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    }
793b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown
794b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown    private static float normalizeAbsoluteBrightness(int value) {
795b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
796330560f53bccd06be805fee1b7988162119d1295Jeff Brown    }
797330560f53bccd06be805fee1b7988162119d1295Jeff Brown
7989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void animateScreenBrightness(int target, int rate) {
7999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
8009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mNotifier.onScreenBrightness(target);
8019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
8039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Runnable mCleanListener = new Runnable() {
8059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
8069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void run() {
8079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            sendUpdatePowerState();
8089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
8109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void setProximitySensorEnabled(boolean enable) {
8129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (enable) {
8139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (!mProximitySensorEnabled) {
8149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mProximitySensorEnabled = true;
8159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mPendingProximity = PROXIMITY_UNKNOWN;
8169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
8179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                        SensorManager.SENSOR_DELAY_NORMAL, mHandler);
8189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
8199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        } else {
8209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mProximitySensorEnabled) {
8219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mProximitySensorEnabled = false;
8229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mProximity = PROXIMITY_UNKNOWN;
8239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
8249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mSensorManager.unregisterListener(mProximitySensorListener);
8259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
8269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
8289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void handleProximitySensorEvent(long time, boolean positive) {
8309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
8319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return; // no change
8329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
8349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return; // no change
8359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // Only accept a proximity sensor reading if it remains
8389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        // stable for the entire debounce delay.
8399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
84093cbbb25a56356cd36523809783a277fe92e312eJeff Brown        if (positive) {
84193cbbb25a56356cd36523809783a277fe92e312eJeff Brown            mPendingProximity = PROXIMITY_POSITIVE;
84293cbbb25a56356cd36523809783a277fe92e312eJeff Brown            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
84393cbbb25a56356cd36523809783a277fe92e312eJeff Brown        } else {
84493cbbb25a56356cd36523809783a277fe92e312eJeff Brown            mPendingProximity = PROXIMITY_NEGATIVE;
84593cbbb25a56356cd36523809783a277fe92e312eJeff Brown            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
84693cbbb25a56356cd36523809783a277fe92e312eJeff Brown        }
8479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        debounceProximitySensor();
8489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
8499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void debounceProximitySensor() {
8519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mPendingProximity != PROXIMITY_UNKNOWN) {
8529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            final long now = SystemClock.uptimeMillis();
8539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mPendingProximityDebounceTime <= now) {
8549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mProximity = mPendingProximity;
8559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                sendUpdatePowerState();
8569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else {
8579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
8589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                msg.setAsynchronous(true);
8599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
8609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
8619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
8629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
8639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
864330560f53bccd06be805fee1b7988162119d1295Jeff Brown    private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
8659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (enable) {
8669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (!mLightSensorEnabled) {
867330560f53bccd06be805fee1b7988162119d1295Jeff Brown                updateAutoBrightness = true;
8689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mLightSensorEnabled = true;
8699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mLightSensorEnableTime = SystemClock.uptimeMillis();
8709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
871e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
8729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
8739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        } else {
8749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mLightSensorEnabled) {
8759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mLightSensorEnabled = false;
8764f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                mAmbientLuxValid = false;
8774f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                mRecentLightSamples = 0;
8789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
8799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                mSensorManager.unregisterListener(mLightSensorListener);
8809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
8819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
882330560f53bccd06be805fee1b7988162119d1295Jeff Brown        if (updateAutoBrightness) {
883330560f53bccd06be805fee1b7988162119d1295Jeff Brown            updateAutoBrightness(false);
884330560f53bccd06be805fee1b7988162119d1295Jeff Brown        }
8859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
8869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
8879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void handleLightSensorEvent(long time, float lux) {
888e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
889e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
890e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        applyLightSensorMeasurement(time, lux);
891e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        updateAmbientLux(time);
892e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    }
893e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
894e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown    private void applyLightSensorMeasurement(long time, float lux) {
8954f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // Update our filters.
8964f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        mRecentLightSamples += 1;
8974f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        if (mRecentLightSamples == 1) {
8984f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            mRecentShortTermAverageLux = lux;
8994f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            mRecentLongTermAverageLux = lux;
9004f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        } else {
9014f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            final long timeDelta = time - mLastObservedLuxTime;
9024f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux)
9034f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                    * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
9044f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux)
9054f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                    * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
9069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
9079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
9084f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // Remember this sample value.
9094f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        mLastObservedLux = lux;
9104f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        mLastObservedLuxTime = time;
9119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
9129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
9134f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private void updateAmbientLux(long time) {
9144f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // If the light sensor was just turned on then immediately update our initial
9154f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // estimate of the current ambient light level.
9164f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        if (!mAmbientLuxValid
9174f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                || (time - mLightSensorEnableTime) < mLightSensorWarmUpTimeConfig) {
918e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mAmbientLux = mRecentShortTermAverageLux;
919e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mAmbientLuxValid = true;
920e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mDebounceLuxDirection = 0;
921e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mDebounceLuxTime = time;
9224f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            if (DEBUG) {
923e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                Slog.d(TAG, "updateAmbientLux: Initializing: "
9244f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
925e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
926e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", mAmbientLux=" + mAmbientLux);
9274f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            }
9284f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            updateAutoBrightness(true);
9294f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            return;
9304f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        }
9319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
9324f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // Determine whether the ambient environment appears to be brightening.
933e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        float brighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
934e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        if (mRecentShortTermAverageLux > brighteningLuxThreshold
935e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                && mRecentLongTermAverageLux > brighteningLuxThreshold) {
936e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            if (mDebounceLuxDirection <= 0) {
937e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mDebounceLuxDirection = 1;
938e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mDebounceLuxTime = time;
939e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                if (DEBUG) {
940e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                    Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for "
941e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + BRIGHTENING_LIGHT_DEBOUNCE + " ms: "
942e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + "brighteningLuxThreshold=" + brighteningLuxThreshold
943e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
944e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
945e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mAmbientLux=" + mAmbientLux);
946e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                }
947e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            }
948e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE;
9494f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            if (time >= debounceTime) {
950e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mAmbientLux = mRecentShortTermAverageLux;
9519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                if (DEBUG) {
9524f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                    Slog.d(TAG, "updateAmbientLux: Brightened: "
953e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + "brighteningLuxThreshold=" + brighteningLuxThreshold
9544f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
955e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
956e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mAmbientLux=" + mAmbientLux);
9579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                }
9589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                updateAutoBrightness(true);
9594f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            } else {
9604f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
9614f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            }
9624f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            return;
9634f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        }
9649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
9654f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        // Determine whether the ambient environment appears to be darkening.
966e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        float darkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
967e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        if (mRecentShortTermAverageLux < darkeningLuxThreshold
968e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                && mRecentLongTermAverageLux < darkeningLuxThreshold) {
969e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            if (mDebounceLuxDirection >= 0) {
970e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mDebounceLuxDirection = -1;
971e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mDebounceLuxTime = time;
972e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                if (DEBUG) {
973e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                    Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for "
974e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + DARKENING_LIGHT_DEBOUNCE + " ms: "
975e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + "darkeningLuxThreshold=" + darkeningLuxThreshold
976e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
977e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
978e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mAmbientLux=" + mAmbientLux);
979e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                }
980e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            }
981e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE;
9824f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown            if (time >= debounceTime) {
983e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                // Be conservative about reducing the brightness, only reduce it a little bit
984e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                // at a time to avoid having to bump it up again soon.
985e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                mAmbientLux = Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux);
9864f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                if (DEBUG) {
9874f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                    Slog.d(TAG, "updateAmbientLux: Darkened: "
988e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + "darkeningLuxThreshold=" + darkeningLuxThreshold
9894f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
990e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
991e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + ", mAmbientLux=" + mAmbientLux);
9924f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                }
9934f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                updateAutoBrightness(true);
9949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            } else {
9954f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
9969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
997e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            return;
998e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        }
999e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
1000e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // No change or change is within the hysteresis thresholds.
1001e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        if (mDebounceLuxDirection != 0) {
1002e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mDebounceLuxDirection = 0;
1003e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mDebounceLuxTime = time;
1004e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            if (DEBUG) {
1005e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                Slog.d(TAG, "updateAmbientLux: Canceled debounce: "
1006e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + "brighteningLuxThreshold=" + brighteningLuxThreshold
1007e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", darkeningLuxThreshold=" + darkeningLuxThreshold
1008e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
1009e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
1010e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                        + ", mAmbientLux=" + mAmbientLux);
1011e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            }
1012e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        }
1013e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown
1014e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // If the light level does not change, then the sensor may not report
1015e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // a new value.  This can cause problems for the auto-brightness algorithm
1016e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // because the filters might not be updated.  To work around it, we want to
1017e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // make sure to update the filters whenever the observed light level could
1018e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        // possibly exceed one of the hysteresis thresholds.
1019e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        if (mLastObservedLux > brighteningLuxThreshold
1020e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                || mLastObservedLux < darkeningLuxThreshold) {
1021e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
1022e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                    time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS);
10239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
10249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
10259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
10264f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    private void debounceLightSensor() {
1027e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        if (mLightSensorEnabled) {
1028e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            long time = SystemClock.uptimeMillis();
1029e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) {
1030e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                if (DEBUG) {
1031e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                    Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement "
1032e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                            + "after " + (time - mLastObservedLuxTime) + " ms.");
1033e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                }
1034e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown                applyLightSensorMeasurement(time, mLastObservedLux);
1035e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            }
1036e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown            updateAmbientLux(time);
1037e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        }
10384f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown    }
10394f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown
10409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void updateAutoBrightness(boolean sendUpdate) {
10414f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        if (!mAmbientLuxValid) {
10429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return;
10439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
10449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
10454f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
1046330560f53bccd06be805fee1b7988162119d1295Jeff Brown        float gamma = 1.0f;
1047330560f53bccd06be805fee1b7988162119d1295Jeff Brown
1048330560f53bccd06be805fee1b7988162119d1295Jeff Brown        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
1049330560f53bccd06be805fee1b7988162119d1295Jeff Brown                && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) {
1050330560f53bccd06be805fee1b7988162119d1295Jeff Brown            final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
1051330560f53bccd06be805fee1b7988162119d1295Jeff Brown                    Math.min(1.0f, Math.max(-1.0f,
1052330560f53bccd06be805fee1b7988162119d1295Jeff Brown                            -mPowerRequest.screenAutoBrightnessAdjustment)));
1053330560f53bccd06be805fee1b7988162119d1295Jeff Brown            gamma *= adjGamma;
1054330560f53bccd06be805fee1b7988162119d1295Jeff Brown            if (DEBUG) {
1055330560f53bccd06be805fee1b7988162119d1295Jeff Brown                Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
1056330560f53bccd06be805fee1b7988162119d1295Jeff Brown            }
1057330560f53bccd06be805fee1b7988162119d1295Jeff Brown        }
1058330560f53bccd06be805fee1b7988162119d1295Jeff Brown
1059aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        if (USE_TWILIGHT_ADJUSTMENT) {
1060aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            TwilightState state = mTwilight.getCurrentState();
1061aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            if (state != null && state.isNight()) {
1062aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                final long now = System.currentTimeMillis();
1063aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                final float earlyGamma =
1064aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
1065aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                final float lateGamma =
1066aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
1067aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                gamma *= earlyGamma * lateGamma;
1068aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                if (DEBUG) {
1069aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
1070aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                            + ", lateGamma=" + lateGamma);
1071aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                }
1072aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            }
1073aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
1074aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1075330560f53bccd06be805fee1b7988162119d1295Jeff Brown        if (gamma != 1.0f) {
1076330560f53bccd06be805fee1b7988162119d1295Jeff Brown            final float in = value;
1077330560f53bccd06be805fee1b7988162119d1295Jeff Brown            value = FloatMath.pow(value, gamma);
1078330560f53bccd06be805fee1b7988162119d1295Jeff Brown            if (DEBUG) {
1079330560f53bccd06be805fee1b7988162119d1295Jeff Brown                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
1080330560f53bccd06be805fee1b7988162119d1295Jeff Brown                        + ", in=" + in + ", out=" + value);
1081330560f53bccd06be805fee1b7988162119d1295Jeff Brown            }
1082330560f53bccd06be805fee1b7988162119d1295Jeff Brown        }
1083330560f53bccd06be805fee1b7988162119d1295Jeff Brown
1084330560f53bccd06be805fee1b7988162119d1295Jeff Brown        int newScreenAutoBrightness = clampScreenBrightness(
10854f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                Math.round(value * PowerManager.BRIGHTNESS_ON));
10869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mScreenAutoBrightness != newScreenAutoBrightness) {
10879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (DEBUG) {
10889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
1089330560f53bccd06be805fee1b7988162119d1295Jeff Brown                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
10901a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown                        + newScreenAutoBrightness);
10919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
10929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
10939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mScreenAutoBrightness = newScreenAutoBrightness;
1094330560f53bccd06be805fee1b7988162119d1295Jeff Brown            mLastScreenAutoBrightnessGamma = gamma;
10959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (sendUpdate) {
10969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                sendUpdatePowerState();
10979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
10989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
10999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
11009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1101aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
1102aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        if (lastSunset < 0 || nextSunrise < 0
1103aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                || now < lastSunset || now > nextSunrise) {
1104aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            return 1.0f;
1105aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
1106aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1107aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
1108aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
1109aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
1110aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
1111aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1112aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
1113aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
1114aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
1115aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
1116aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1117aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
1118aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    }
1119aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1120aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private static float lerp(float x, float y, float alpha) {
1121aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        return x + (y - x) * alpha;
1122aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    }
1123aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
11249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void sendOnStateChanged() {
11259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mCallbackHandler.post(mOnStateChangedRunnable);
11269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
11279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
11289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Runnable mOnStateChangedRunnable = new Runnable() {
11299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
11309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void run() {
11319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mCallbacks.onStateChanged();
11329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
11339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
11349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
113593cbbb25a56356cd36523809783a277fe92e312eJeff Brown    private void sendOnProximityPositive() {
113693cbbb25a56356cd36523809783a277fe92e312eJeff Brown        mCallbackHandler.post(mOnProximityPositiveRunnable);
113793cbbb25a56356cd36523809783a277fe92e312eJeff Brown    }
113893cbbb25a56356cd36523809783a277fe92e312eJeff Brown
113993cbbb25a56356cd36523809783a277fe92e312eJeff Brown    private final Runnable mOnProximityPositiveRunnable = new Runnable() {
114093cbbb25a56356cd36523809783a277fe92e312eJeff Brown        @Override
114193cbbb25a56356cd36523809783a277fe92e312eJeff Brown        public void run() {
114293cbbb25a56356cd36523809783a277fe92e312eJeff Brown            mCallbacks.onProximityPositive();
114393cbbb25a56356cd36523809783a277fe92e312eJeff Brown        }
114493cbbb25a56356cd36523809783a277fe92e312eJeff Brown    };
114593cbbb25a56356cd36523809783a277fe92e312eJeff Brown
11469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void sendOnProximityNegative() {
11479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mCallbackHandler.post(mOnProximityNegativeRunnable);
11489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
11499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
11509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Runnable mOnProximityNegativeRunnable = new Runnable() {
11519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
11529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void run() {
11539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mCallbacks.onProximityNegative();
11549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
11559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
11569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1157bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void dump(final PrintWriter pw) {
11589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        synchronized (mLock) {
11599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println();
11609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("Display Controller Locked State:");
11619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
11629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
11639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
11649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mPendingWaitForNegativeProximityLocked="
11659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    + mPendingWaitForNegativeProximityLocked);
11669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
11679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
11689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
11699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println();
11709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("Display Controller Configuration:");
11719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
1172b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
1173b76eebff47653daf0c98119aeb68b57cb9a46f9dJeff Brown        pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
11749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mUseSoftwareAutoBrightnessConfig="
11759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                + mUseSoftwareAutoBrightnessConfig);
11761a30b55036c2279d72ba69cb1107ec5f6f40d5e9Jeff Brown        pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
11779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
11789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1179bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mHandler.runWithScissors(new Runnable() {
1180bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
1181bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void run() {
1182bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                dumpLocal(pw);
11839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
11844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }, 1000);
11859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
11869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
11879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private void dumpLocal(PrintWriter pw) {
11889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println();
11899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("Display Controller Thread State:");
11909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mPowerRequest=" + mPowerRequest);
11919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
11929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
11939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mProximitySensor=" + mProximitySensor);
11949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
11959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mProximityThreshold=" + mProximityThreshold);
11969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mProximity=" + proximityToString(mProximity));
11979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mPendingProximity=" + proximityToString(mPendingProximity));
11989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mPendingProximityDebounceTime="
11999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                + TimeUtils.formatUptime(mPendingProximityDebounceTime));
12009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
12019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mLightSensor=" + mLightSensor);
12039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
12049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mLightSensorEnableTime="
12059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                + TimeUtils.formatUptime(mLightSensorEnableTime));
12064f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mAmbientLux=" + mAmbientLux);
12074f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
12084f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mLastObservedLux=" + mLastObservedLux);
12094f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mLastObservedLuxTime="
12104f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown                + TimeUtils.formatUptime(mLastObservedLuxTime));
12119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
12124f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mRecentShortTermAverageLux=" + mRecentShortTermAverageLux);
12134f0e969eabc336f6dfa31c6218efc1b3dec55139Jeff Brown        pw.println("  mRecentLongTermAverageLux=" + mRecentLongTermAverageLux);
1214e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        pw.println("  mDebounceLuxDirection=" + mDebounceLuxDirection);
1215e941b1e27f6aad8a351c3caa3e0ad5f53dbf3707Jeff Brown        pw.println("  mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime));
12169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
12179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
1218330560f53bccd06be805fee1b7988162119d1295Jeff Brown        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
1219aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
12209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mElectronBeamOnAnimator != null) {
12229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mElectronBeamOnAnimator.isStarted()=" +
12239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    mElectronBeamOnAnimator.isStarted());
12249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mElectronBeamOffAnimator != null) {
12269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            pw.println("  mElectronBeamOffAnimator.isStarted()=" +
12279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    mElectronBeamOffAnimator.isStarted());
12289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        if (mPowerState != null) {
12319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mPowerState.dump(pw);
12329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
12349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static String proximityToString(int state) {
12369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        switch (state) {
12379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            case PROXIMITY_UNKNOWN:
12389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return "Unknown";
12399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            case PROXIMITY_NEGATIVE:
12409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return "Negative";
12419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            case PROXIMITY_POSITIVE:
12429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return "Positive";
12439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            default:
12449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return Integer.toString(state);
12459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
12479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static boolean wantScreenOn(int state) {
12499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        switch (state) {
12509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            case DisplayPowerRequest.SCREEN_STATE_BRIGHT:
12519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            case DisplayPowerRequest.SCREEN_STATE_DIM:
12529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                return true;
12539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        return false;
12559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
12569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
12589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Asynchronous callbacks from the power controller to the power manager service.
12599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
12609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public interface Callbacks {
12619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        void onStateChanged();
126293cbbb25a56356cd36523809783a277fe92e312eJeff Brown        void onProximityPositive();
12639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        void onProximityNegative();
12649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
12659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final class DisplayControllerHandler extends Handler {
12679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public DisplayControllerHandler(Looper looper) {
1268a2910d0abbbe18ba1710dfd4a31af45769632255Jeff Brown            super(looper, null, true /*async*/);
12699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
12729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void handleMessage(Message msg) {
12739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            switch (msg.what) {
12749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                case MSG_UPDATE_POWER_STATE:
12759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    updatePowerState();
12769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    break;
12779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                case MSG_PROXIMITY_SENSOR_DEBOUNCED:
12799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    debounceProximitySensor();
12809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    break;
12819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                case MSG_LIGHT_SENSOR_DEBOUNCED:
12839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    debounceLightSensor();
12849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                    break;
12859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
12869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
12889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
12899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
12909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
12919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onSensorChanged(SensorEvent event) {
12929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mProximitySensorEnabled) {
12939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                final long time = SystemClock.uptimeMillis();
12949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                final float distance = event.values[0];
12959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                boolean positive = distance >= 0.0f && distance < mProximityThreshold;
12969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                handleProximitySensorEvent(time, positive);
12979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
12989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
12999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
13009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
13019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAccuracyChanged(Sensor sensor, int accuracy) {
13029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            // Not used.
13039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
13049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
13059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
13069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
13079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
13089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onSensorChanged(SensorEvent event) {
13099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (mLightSensorEnabled) {
13109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                final long time = SystemClock.uptimeMillis();
13119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                final float lux = event.values[0];
13129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                handleLightSensorEvent(time, lux);
13139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
13149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
13159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
13169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
13179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void onAccuracyChanged(Sensor sensor, int accuracy) {
13189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            // Not used.
13199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
13209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
1321aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown
1322aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    private final TwilightService.TwilightListener mTwilightListener =
1323aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            new TwilightService.TwilightListener() {
1324aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        @Override
1325aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        public void onTwilightStateChanged() {
1326aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            mTwilightChanged = true;
1327aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown            updatePowerState();
1328aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown        }
1329aa202a6dc33d331cbd9e34a1bb5f74db6284dda6Jeff Brown    };
13309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown}
1331