diff options
author | Jeff Brown <jeffbrown@google.com> | 2014-04-08 17:26:30 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2014-04-08 20:41:46 -0700 |
commit | ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25 (patch) | |
tree | 78e2f02c59770e9be7c865b4e2bc663445639b1b /services/core/java/com/android/server/power | |
parent | ce802f4898c5747038584596d9d689ca30c34c4e (diff) | |
download | frameworks_base-ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25.zip frameworks_base-ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25.tar.gz frameworks_base-ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25.tar.bz2 |
Move display power controller to display manager service. (DO NOT MERGE)
This refactoring is in preparation for enabling the display manager
to have more control over the blanking state of individual displays.
There are no functional changes. Some bits will be cleaned up in
a subsequent patch.
Bug: 13133142
Change-Id: Ib811835e8757449c7899ac61807029baaf998161
Diffstat (limited to 'services/core/java/com/android/server/power')
8 files changed, 59 insertions, 2942 deletions
diff --git a/services/core/java/com/android/server/power/DisplayBlanker.java b/services/core/java/com/android/server/power/DisplayBlanker.java deleted file mode 100644 index 6072053..0000000 --- a/services/core/java/com/android/server/power/DisplayBlanker.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -/** - * Blanks or unblanks all displays. - */ -interface DisplayBlanker { - public void blankAllDisplays(); - public void unblankAllDisplays(); -} diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java deleted file mode 100644 index e83f734..0000000 --- a/services/core/java/com/android/server/power/DisplayPowerController.java +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -import com.android.server.lights.LightsManager; -import com.android.server.twilight.TwilightListener; -import com.android.server.twilight.TwilightManager; -import com.android.server.twilight.TwilightState; - -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.content.Context; -import android.content.res.Resources; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.PowerManager; -import android.os.SystemClock; -import android.text.format.DateUtils; -import android.util.FloatMath; -import android.util.Slog; -import android.util.Spline; -import android.util.TimeUtils; - -import java.io.PrintWriter; - -/** - * Controls the power state of the display. - * - * Handles the proximity sensor, light sensor, and animations between states - * including the screen off animation. - * - * This component acts independently of the rest of the power manager service. - * In particular, it does not share any state and it only communicates - * via asynchronous callbacks to inform the power manager that something has - * changed. - * - * Everything this class does internally is serialized on its handler although - * it may be accessed by other threads from the outside. - * - * Note that the power manager service guarantees that it will hold a suspend - * blocker as long as the display is not ready. So most of the work done here - * does not need to worry about holding a suspend blocker unless it happens - * independently of the display ready signal. - * - * For debugging, you can make the electron beam and brightness animations run - * slower by changing the "animator duration scale" option in Development Settings. - */ -final class DisplayPowerController { - private static final String TAG = "DisplayPowerController"; - - private static boolean DEBUG = false; - private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false; - private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false; - - // If true, uses the electron beam on animation. - // We might want to turn this off if we cannot get a guarantee that the screen - // actually turns on and starts showing new content after the call to set the - // screen state returns. Playing the animation can also be somewhat slow. - private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false; - - // If true, enables the use of the screen auto-brightness adjustment setting. - private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT = - PowerManager.useScreenAutoBrightnessAdjustmentFeature(); - - // The maximum range of gamma adjustment possible using the screen - // auto-brightness adjustment setting. - private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f; - - // The minimum reduction in brightness when dimmed. - private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10; - - // If true, enables the use of the current time as an auto-brightness adjustment. - // The basic idea here is to expand the dynamic range of auto-brightness - // when it is especially dark outside. The light sensor tends to perform - // poorly at low light levels so we compensate for it by making an - // assumption about the environment. - private static final boolean USE_TWILIGHT_ADJUSTMENT = - PowerManager.useTwilightAdjustmentFeature(); - - // Specifies the maximum magnitude of the time of day adjustment. - private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f; - - // The amount of time after or before sunrise over which to start adjusting - // the gamma. We want the change to happen gradually so that it is below the - // threshold of perceptibility and so that the adjustment has maximum effect - // well after dusk. - private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2; - - private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 250; - private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 400; - - private static final int MSG_UPDATE_POWER_STATE = 1; - private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2; - private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3; - - private static final int PROXIMITY_UNKNOWN = -1; - private static final int PROXIMITY_NEGATIVE = 0; - private static final int PROXIMITY_POSITIVE = 1; - - // Proximity sensor debounce delay in milliseconds for positive or negative transitions. - private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0; - private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250; - - // Trigger proximity if distance is less than 5 cm. - private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f; - - // Light sensor event rate in milliseconds. - private static final int LIGHT_SENSOR_RATE_MILLIS = 1000; - - // A rate for generating synthetic light sensor events in the case where the light - // sensor hasn't reported any new data in a while and we need it to update the - // debounce filter. We only synthesize light sensor measurements when needed. - private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS = - LIGHT_SENSOR_RATE_MILLIS * 2; - - // Brightness animation ramp rate in brightness units per second. - private static final int BRIGHTNESS_RAMP_RATE_FAST = 200; - private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; - - // IIR filter time constants in milliseconds for computing two moving averages of - // the light samples. One is a long-term average and the other is a short-term average. - // We can use these filters to assess trends in ambient brightness. - // The short term average gives us a filtered but relatively low latency measurement. - // The long term average informs us about the overall trend. - private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000; - private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000; - - // Stability requirements in milliseconds for accepting a new brightness - // level. This is used for debouncing the light sensor. Different constants - // are used to debounce the light sensor when adapting to brighter or darker environments. - // This parameter controls how quickly brightness changes occur in response to - // an observed change in light level that exceeds the hysteresis threshold. - private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000; - private static final long DARKENING_LIGHT_DEBOUNCE = 8000; - - // Hysteresis constraints for brightening or darkening. - // The recent lux must have changed by at least this fraction relative to the - // current ambient lux before a change will be considered. - private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f; - private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f; - - private final Object mLock = new Object(); - - // Notifier for sending asynchronous notifications. - private final Notifier mNotifier; - - // The display suspend blocker. - // Held while there are pending state change notifications. - private final SuspendBlocker mDisplaySuspendBlocker; - - // The display blanker. - private final DisplayBlanker mDisplayBlanker; - - // Our handler. - private final DisplayControllerHandler mHandler; - - // Asynchronous callbacks into the power manager service. - // Only invoked from the handler thread while no locks are held. - private final Callbacks mCallbacks; - private Handler mCallbackHandler; - - // The lights service. - private final LightsManager mLights; - - // The twilight service. - private final TwilightManager mTwilight; - - // The sensor manager. - private final SensorManager mSensorManager; - - // The proximity sensor, or null if not available or needed. - private Sensor mProximitySensor; - - // The light sensor, or null if not available or needed. - private Sensor mLightSensor; - - // The doze screen brightness. - private final int mScreenBrightnessDozeConfig; - - // The dim screen brightness. - private final int mScreenBrightnessDimConfig; - - // The minimum allowed brightness. - private final int mScreenBrightnessRangeMinimum; - - // The maximum allowed brightness. - private final int mScreenBrightnessRangeMaximum; - - // True if auto-brightness should be used. - private boolean mUseSoftwareAutoBrightnessConfig; - - // The auto-brightness spline adjustment. - // The brightness values have been scaled to a range of 0..1. - private Spline mScreenAutoBrightnessSpline; - - // Amount of time to delay auto-brightness after screen on while waiting for - // the light sensor to warm-up in milliseconds. - // May be 0 if no warm-up is required. - private int mLightSensorWarmUpTimeConfig; - - // True if we should fade the screen while turning it off, false if we should play - // a stylish electron beam animation instead. - private boolean mElectronBeamFadesConfig; - - // The pending power request. - // Initially null until the first call to requestPowerState. - // Guarded by mLock. - private DisplayPowerRequest mPendingRequestLocked; - - // True if a request has been made to wait for the proximity sensor to go negative. - // Guarded by mLock. - private boolean mPendingWaitForNegativeProximityLocked; - - // True if the pending power request or wait for negative proximity flag - // has been changed since the last update occurred. - // Guarded by mLock. - private boolean mPendingRequestChangedLocked; - - // Set to true when the important parts of the pending power request have been applied. - // The important parts are mainly the screen state. Brightness changes may occur - // concurrently. - // Guarded by mLock. - private boolean mDisplayReadyLocked; - - // Set to true if a power state update is required. - // Guarded by mLock. - private boolean mPendingUpdatePowerStateLocked; - - /* The following state must only be accessed by the handler thread. */ - - // The currently requested power state. - // The power controller will progressively update its internal state to match - // the requested power state. Initially null until the first update. - private DisplayPowerRequest mPowerRequest; - - // The current power state. - // Must only be accessed on the handler thread. - private DisplayPowerState mPowerState; - - // True if the device should wait for negative proximity sensor before - // waking up the screen. This is set to false as soon as a negative - // proximity sensor measurement is observed or when the device is forced to - // go to sleep by the user. While true, the screen remains off. - private boolean mWaitingForNegativeProximity; - - // The actual proximity sensor threshold value. - private float mProximityThreshold; - - // Set to true if the proximity sensor listener has been registered - // with the sensor manager. - private boolean mProximitySensorEnabled; - - // The debounced proximity sensor state. - private int mProximity = PROXIMITY_UNKNOWN; - - // The raw non-debounced proximity sensor state. - private int mPendingProximity = PROXIMITY_UNKNOWN; - private long mPendingProximityDebounceTime = -1; // -1 if fully debounced - - // True if the screen was turned off because of the proximity sensor. - // When the screen turns on again, we report user activity to the power manager. - private boolean mScreenOffBecauseOfProximity; - - // True if the screen on is being blocked. - private boolean mScreenOnWasBlocked; - - // The elapsed real time when the screen on was blocked. - private long mScreenOnBlockStartRealTime; - - // Set to true if the light sensor is enabled. - private boolean mLightSensorEnabled; - - // The time when the light sensor was enabled. - private long mLightSensorEnableTime; - - // The currently accepted nominal ambient light level. - private float mAmbientLux; - - // True if mAmbientLux holds a valid value. - private boolean mAmbientLuxValid; - - // The ambient light level threshold at which to brighten or darken the screen. - private float mBrighteningLuxThreshold; - private float mDarkeningLuxThreshold; - - // The most recent light sample. - private float mLastObservedLux; - - // The time of the most light recent sample. - private long mLastObservedLuxTime; - - // The number of light samples collected since the light sensor was enabled. - private int mRecentLightSamples; - - // The long-term and short-term filtered light measurements. - private float mRecentShortTermAverageLux; - private float mRecentLongTermAverageLux; - - // The direction in which the average lux is moving relative to the current ambient lux. - // 0 if not changing or within hysteresis threshold. - // 1 if brightening beyond hysteresis threshold. - // -1 if darkening beyond hysteresis threshold. - private int mDebounceLuxDirection; - - // The time when the average lux last changed direction. - private long mDebounceLuxTime; - - // The screen brightness level that has been chosen by the auto-brightness - // algorithm. The actual brightness should ramp towards this value. - // We preserve this value even when we stop using the light sensor so - // that we can quickly revert to the previous auto-brightness level - // while the light sensor warms up. - // Use -1 if there is no current auto-brightness value available. - private int mScreenAutoBrightness = -1; - - // The last screen auto-brightness gamma. (For printing in dump() only.) - private float mLastScreenAutoBrightnessGamma = 1.0f; - - // True if the screen auto-brightness value is actually being used to - // set the display brightness. - private boolean mUsingScreenAutoBrightness; - - // Animators. - private ObjectAnimator mElectronBeamOnAnimator; - private ObjectAnimator mElectronBeamOffAnimator; - private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; - - // Twilight changed. We might recalculate auto-brightness values. - private boolean mTwilightChanged; - - /** - * Creates the display power controller. - */ - public DisplayPowerController(Looper looper, Context context, Notifier notifier, - LightsManager lights, TwilightManager twilight, SensorManager sensorManager, - SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker, - Callbacks callbacks, Handler callbackHandler) { - mHandler = new DisplayControllerHandler(looper); - mNotifier = notifier; - mDisplaySuspendBlocker = displaySuspendBlocker; - mDisplayBlanker = displayBlanker; - mCallbacks = callbacks; - mCallbackHandler = callbackHandler; - - mLights = lights; - mTwilight = twilight; - mSensorManager = sensorManager; - - final Resources resources = context.getResources(); - - mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessDoze)); - - mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessDim)); - - int screenBrightnessMinimum = Math.min(resources.getInteger( - com.android.internal.R.integer.config_screenBrightnessSettingMinimum), - mScreenBrightnessDimConfig); - - mUseSoftwareAutoBrightnessConfig = resources.getBoolean( - com.android.internal.R.bool.config_automatic_brightness_available); - if (mUseSoftwareAutoBrightnessConfig) { - int[] lux = resources.getIntArray( - com.android.internal.R.array.config_autoBrightnessLevels); - int[] screenBrightness = resources.getIntArray( - com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); - - mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); - if (mScreenAutoBrightnessSpline == null) { - Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " - + "(size " + screenBrightness.length + ") " - + "must be monotic and have exactly one more entry than " - + "config_autoBrightnessLevels (size " + lux.length + ") " - + "which must be strictly increasing. " - + "Auto-brightness will be disabled."); - mUseSoftwareAutoBrightnessConfig = false; - } else { - if (screenBrightness[0] < screenBrightnessMinimum) { - screenBrightnessMinimum = screenBrightness[0]; - } - } - - mLightSensorWarmUpTimeConfig = resources.getInteger( - com.android.internal.R.integer.config_lightSensorWarmupTime); - } - - mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum); - mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON; - - mElectronBeamFadesConfig = resources.getBoolean( - com.android.internal.R.bool.config_animateScreenLights); - - if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { - mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); - if (mProximitySensor != null) { - mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), - TYPICAL_PROXIMITY_THRESHOLD); - } - } - - if (mUseSoftwareAutoBrightnessConfig - && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) { - mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); - } - - if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) { - mTwilight.registerListener(mTwilightListener, mHandler); - } - } - - private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) { - try { - final int n = brightness.length; - float[] x = new float[n]; - float[] y = new float[n]; - y[0] = normalizeAbsoluteBrightness(brightness[0]); - for (int i = 1; i < n; i++) { - x[i] = lux[i - 1]; - y[i] = normalizeAbsoluteBrightness(brightness[i]); - } - - Spline spline = Spline.createMonotoneCubicSpline(x, y); - if (DEBUG) { - Slog.d(TAG, "Auto-brightness spline: " + spline); - for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) { - Slog.d(TAG, String.format(" %7.1f: %7.1f", v, spline.interpolate(v))); - } - } - return spline; - } catch (IllegalArgumentException ex) { - Slog.e(TAG, "Could not create auto-brightness spline.", ex); - return null; - } - } - - /** - * Returns true if the proximity sensor screen-off function is available. - */ - public boolean isProximitySensorAvailable() { - return mProximitySensor != null; - } - - /** - * Requests a new power state. - * The controller makes a copy of the provided object and then - * begins adjusting the power state to match what was requested. - * - * @param request The requested power state. - * @param waitForNegativeProximity If true, issues a request to wait for - * negative proximity before turning the screen back on, assuming the screen - * was turned off by the proximity sensor. - * @return True if display is ready, false if there are important changes that must - * be made asynchronously (such as turning the screen on), in which case the caller - * should grab a wake lock, watch for {@link Callbacks#onStateChanged()} then try - * the request again later until the state converges. - */ - public boolean requestPowerState(DisplayPowerRequest request, - boolean waitForNegativeProximity) { - if (DEBUG) { - Slog.d(TAG, "requestPowerState: " - + request + ", waitForNegativeProximity=" + waitForNegativeProximity); - } - - synchronized (mLock) { - boolean changed = false; - - if (waitForNegativeProximity - && !mPendingWaitForNegativeProximityLocked) { - mPendingWaitForNegativeProximityLocked = true; - changed = true; - } - - if (mPendingRequestLocked == null) { - mPendingRequestLocked = new DisplayPowerRequest(request); - changed = true; - } else if (!mPendingRequestLocked.equals(request)) { - mPendingRequestLocked.copyFrom(request); - changed = true; - } - - if (changed) { - mDisplayReadyLocked = false; - } - - if (changed && !mPendingRequestChangedLocked) { - mPendingRequestChangedLocked = true; - sendUpdatePowerStateLocked(); - } - - return mDisplayReadyLocked; - } - } - - private void sendUpdatePowerState() { - synchronized (mLock) { - sendUpdatePowerStateLocked(); - } - } - - private void sendUpdatePowerStateLocked() { - if (!mPendingUpdatePowerStateLocked) { - mPendingUpdatePowerStateLocked = true; - Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); - msg.setAsynchronous(true); - mHandler.sendMessage(msg); - } - } - - private void initialize() { - mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker, - mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT)); - - mElectronBeamOnAnimator = ObjectAnimator.ofFloat( - mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f); - mElectronBeamOnAnimator.setDuration(ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS); - mElectronBeamOnAnimator.addListener(mAnimatorListener); - - mElectronBeamOffAnimator = ObjectAnimator.ofFloat( - mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 1.0f, 0.0f); - mElectronBeamOffAnimator.setDuration(ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS); - mElectronBeamOffAnimator.addListener(mAnimatorListener); - - mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( - mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); - } - - private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { - } - @Override - public void onAnimationEnd(Animator animation) { - sendUpdatePowerState(); - } - @Override - public void onAnimationRepeat(Animator animation) { - } - @Override - public void onAnimationCancel(Animator animation) { - } - }; - - private void updatePowerState() { - // Update the power state request. - final boolean mustNotify; - boolean mustInitialize = false; - boolean updateAutoBrightness = mTwilightChanged; - boolean wasDimOrDoze = false; - mTwilightChanged = false; - - synchronized (mLock) { - mPendingUpdatePowerStateLocked = false; - if (mPendingRequestLocked == null) { - return; // wait until first actual power request - } - - if (mPowerRequest == null) { - mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); - mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; - mPendingWaitForNegativeProximityLocked = false; - mPendingRequestChangedLocked = false; - mustInitialize = true; - } else if (mPendingRequestChangedLocked) { - if (mPowerRequest.screenAutoBrightnessAdjustment - != mPendingRequestLocked.screenAutoBrightnessAdjustment) { - updateAutoBrightness = true; - } - wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM - || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE); - mPowerRequest.copyFrom(mPendingRequestLocked); - mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; - mPendingWaitForNegativeProximityLocked = false; - mPendingRequestChangedLocked = false; - mDisplayReadyLocked = false; - } - - mustNotify = !mDisplayReadyLocked; - } - - // Initialize things the first time the power state is changed. - if (mustInitialize) { - initialize(); - } - - // Apply the proximity sensor. - if (mProximitySensor != null) { - if (mPowerRequest.useProximitySensor - && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { - setProximitySensorEnabled(true); - if (!mScreenOffBecauseOfProximity - && mProximity == PROXIMITY_POSITIVE) { - mScreenOffBecauseOfProximity = true; - sendOnProximityPositiveWithWakelock(); - } - } else if (mWaitingForNegativeProximity - && mScreenOffBecauseOfProximity - && mProximity == PROXIMITY_POSITIVE - && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { - setProximitySensorEnabled(true); - } else { - setProximitySensorEnabled(false); - mWaitingForNegativeProximity = false; - } - if (mScreenOffBecauseOfProximity - && mProximity != PROXIMITY_POSITIVE) { - mScreenOffBecauseOfProximity = false; - sendOnProximityNegativeWithWakelock(); - } - } else { - mWaitingForNegativeProximity = false; - } - - // Turn on the light sensor if needed. - if (mLightSensor != null) { - setLightSensorEnabled(mPowerRequest.wantLightSensorEnabled(), - updateAutoBrightness); - } - - // Set the screen brightness. - if (mPowerRequest.wantScreenOnAny()) { - int target; - boolean slow; - if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) { - // Use current auto-brightness value. - target = mScreenAutoBrightness; - slow = mUsingScreenAutoBrightness; - mUsingScreenAutoBrightness = true; - } else { - // Light sensor is disabled or not ready yet. - // Use the current brightness setting from the request, which is expected - // provide a nominal default value for the case where auto-brightness - // is not ready yet. - target = mPowerRequest.screenBrightness; - slow = false; - mUsingScreenAutoBrightness = false; - } - if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE) { - // Dim quickly to the doze state. - target = mScreenBrightnessDozeConfig; - slow = false; - } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) { - // Dim quickly by at least some minimum amount. - target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION, - mScreenBrightnessDimConfig); - slow = false; - } else if (wasDimOrDoze) { - // Brighten quickly. - slow = false; - } - animateScreenBrightness(clampScreenBrightness(target), - slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); - } else { - // Screen is off. Don't bother changing the brightness. - mUsingScreenAutoBrightness = false; - } - - // Animate the screen on or off unless blocked. - if (mScreenOffBecauseOfProximity) { - // Screen off due to proximity. - setScreenOn(false); - unblockScreenOn(); - } else if (mPowerRequest.wantScreenOnAny()) { - // Want screen on. - // Wait for previous off animation to complete beforehand. - // It is relatively short but if we cancel it and switch to the - // on animation immediately then the results are pretty ugly. - if (!mElectronBeamOffAnimator.isStarted()) { - // Turn the screen on. The contents of the screen may not yet - // be visible if the electron beam has not been dismissed because - // its last frame of animation is solid black. - setScreenOn(true); - - if (mPowerRequest.blockScreenOn - && mPowerState.getElectronBeamLevel() == 0.0f) { - blockScreenOn(); - } else { - unblockScreenOn(); - if (USE_ELECTRON_BEAM_ON_ANIMATION) { - if (!mElectronBeamOnAnimator.isStarted()) { - if (mPowerState.getElectronBeamLevel() == 1.0f) { - mPowerState.dismissElectronBeam(); - } else if (mPowerState.prepareElectronBeam( - mElectronBeamFadesConfig ? - ElectronBeam.MODE_FADE : - ElectronBeam.MODE_WARM_UP)) { - mElectronBeamOnAnimator.start(); - } else { - mElectronBeamOnAnimator.end(); - } - } - } else { - mPowerState.setElectronBeamLevel(1.0f); - mPowerState.dismissElectronBeam(); - } - } - } - } else { - // Want screen off. - // Wait for previous on animation to complete beforehand. - unblockScreenOn(); - if (!mElectronBeamOnAnimator.isStarted()) { - if (!mElectronBeamOffAnimator.isStarted()) { - if (mPowerState.getElectronBeamLevel() == 0.0f) { - setScreenOn(false); - } else if (mPowerState.prepareElectronBeam( - mElectronBeamFadesConfig ? - ElectronBeam.MODE_FADE : - ElectronBeam.MODE_COOL_DOWN) - && mPowerState.isScreenOn()) { - mElectronBeamOffAnimator.start(); - } else { - mElectronBeamOffAnimator.end(); - } - } - } - } - - // Report whether the display is ready for use. - // We mostly care about the screen state here, ignoring brightness changes - // which will be handled asynchronously. - if (mustNotify - && !mScreenOnWasBlocked - && !mElectronBeamOnAnimator.isStarted() - && !mElectronBeamOffAnimator.isStarted() - && mPowerState.waitUntilClean(mCleanListener)) { - synchronized (mLock) { - if (!mPendingRequestChangedLocked) { - mDisplayReadyLocked = true; - - if (DEBUG) { - Slog.d(TAG, "Display ready!"); - } - } - } - sendOnStateChangedWithWakelock(); - } - } - - private void blockScreenOn() { - if (!mScreenOnWasBlocked) { - mScreenOnWasBlocked = true; - if (DEBUG) { - Slog.d(TAG, "Blocked screen on."); - mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime(); - } - } - } - - private void unblockScreenOn() { - if (mScreenOnWasBlocked) { - mScreenOnWasBlocked = false; - long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; - if (delay > 1000 || DEBUG) { - Slog.d(TAG, "Unblocked screen on after " + delay + " ms"); - } - } - } - - private void setScreenOn(boolean on) { - if (mPowerState.isScreenOn() != on) { - mPowerState.setScreenOn(on); - if (on) { - mNotifier.onScreenOn(); - } else { - mNotifier.onScreenOff(); - } - } - } - - private int clampScreenBrightness(int value) { - return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum); - } - - private static int clampAbsoluteBrightness(int value) { - return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); - } - - private static int clamp(int value, int min, int max) { - if (value <= min) { - return min; - } - if (value >= max) { - return max; - } - return value; - } - - private static float normalizeAbsoluteBrightness(int value) { - return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON; - } - - private void animateScreenBrightness(int target, int rate) { - if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { - mNotifier.onScreenBrightness(target); - } - } - - private final Runnable mCleanListener = new Runnable() { - @Override - public void run() { - sendUpdatePowerState(); - } - }; - - private void setProximitySensorEnabled(boolean enable) { - if (enable) { - if (!mProximitySensorEnabled) { - // Register the listener. - // Proximity sensor state already cleared initially. - mProximitySensorEnabled = true; - mSensorManager.registerListener(mProximitySensorListener, mProximitySensor, - SensorManager.SENSOR_DELAY_NORMAL, mHandler); - } - } else { - if (mProximitySensorEnabled) { - // Unregister the listener. - // Clear the proximity sensor state for next time. - mProximitySensorEnabled = false; - mProximity = PROXIMITY_UNKNOWN; - mPendingProximity = PROXIMITY_UNKNOWN; - mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); - mSensorManager.unregisterListener(mProximitySensorListener); - clearPendingProximityDebounceTime(); // release wake lock (must be last) - } - } - } - - private void handleProximitySensorEvent(long time, boolean positive) { - if (mProximitySensorEnabled) { - if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) { - return; // no change - } - if (mPendingProximity == PROXIMITY_POSITIVE && positive) { - return; // no change - } - - // Only accept a proximity sensor reading if it remains - // stable for the entire debounce delay. We hold a wake lock while - // debouncing the sensor. - mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED); - if (positive) { - mPendingProximity = PROXIMITY_POSITIVE; - setPendingProximityDebounceTime( - time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock - } else { - mPendingProximity = PROXIMITY_NEGATIVE; - setPendingProximityDebounceTime( - time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock - } - - // Debounce the new sensor reading. - debounceProximitySensor(); - } - } - - private void debounceProximitySensor() { - if (mProximitySensorEnabled - && mPendingProximity != PROXIMITY_UNKNOWN - && mPendingProximityDebounceTime >= 0) { - final long now = SystemClock.uptimeMillis(); - if (mPendingProximityDebounceTime <= now) { - // Sensor reading accepted. Apply the change then release the wake lock. - mProximity = mPendingProximity; - updatePowerState(); - clearPendingProximityDebounceTime(); // release wake lock (must be last) - } else { - // Need to wait a little longer. - // Debounce again later. We continue holding a wake lock while waiting. - Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED); - msg.setAsynchronous(true); - mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime); - } - } - } - - private void clearPendingProximityDebounceTime() { - if (mPendingProximityDebounceTime >= 0) { - mPendingProximityDebounceTime = -1; - mDisplaySuspendBlocker.release(); // release wake lock - } - } - - private void setPendingProximityDebounceTime(long debounceTime) { - if (mPendingProximityDebounceTime < 0) { - mDisplaySuspendBlocker.acquire(); // acquire wake lock - } - mPendingProximityDebounceTime = debounceTime; - } - - private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) { - if (enable) { - if (!mLightSensorEnabled) { - updateAutoBrightness = true; - mLightSensorEnabled = true; - mLightSensorEnableTime = SystemClock.uptimeMillis(); - mSensorManager.registerListener(mLightSensorListener, mLightSensor, - LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler); - } - } else { - if (mLightSensorEnabled) { - mLightSensorEnabled = false; - mAmbientLuxValid = false; - mRecentLightSamples = 0; - mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED); - mSensorManager.unregisterListener(mLightSensorListener); - } - } - if (updateAutoBrightness) { - updateAutoBrightness(false); - } - } - - private void handleLightSensorEvent(long time, float lux) { - mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED); - - applyLightSensorMeasurement(time, lux); - updateAmbientLux(time); - } - - private void applyLightSensorMeasurement(long time, float lux) { - // Update our filters. - mRecentLightSamples += 1; - if (mRecentLightSamples == 1) { - mRecentShortTermAverageLux = lux; - mRecentLongTermAverageLux = lux; - } else { - final long timeDelta = time - mLastObservedLuxTime; - mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux) - * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta); - mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux) - * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta); - } - - // Remember this sample value. - mLastObservedLux = lux; - mLastObservedLuxTime = time; - } - - private void setAmbientLux(float lux) { - mAmbientLux = lux; - mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS); - mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS); - } - - private void updateAmbientLux(long time) { - // If the light sensor was just turned on then immediately update our initial - // estimate of the current ambient light level. - if (!mAmbientLuxValid) { - final long timeWhenSensorWarmedUp = - mLightSensorWarmUpTimeConfig + mLightSensorEnableTime; - if (time < timeWhenSensorWarmedUp) { - mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, - timeWhenSensorWarmedUp); - return; - } - setAmbientLux(mRecentShortTermAverageLux); - mAmbientLuxValid = true; - mDebounceLuxDirection = 0; - mDebounceLuxTime = time; - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Initializing: " - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - updateAutoBrightness(true); - } else if (mRecentShortTermAverageLux > mBrighteningLuxThreshold - && mRecentLongTermAverageLux > mBrighteningLuxThreshold) { - // The ambient environment appears to be brightening. - if (mDebounceLuxDirection <= 0) { - mDebounceLuxDirection = 1; - mDebounceLuxTime = time; - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for " - + BRIGHTENING_LIGHT_DEBOUNCE + " ms: " - + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - } - long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE; - if (time < debounceTime) { - mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime); - return; - } - setAmbientLux(mRecentShortTermAverageLux); - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Brightened: " - + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - updateAutoBrightness(true); - } else if (mRecentShortTermAverageLux < mDarkeningLuxThreshold - && mRecentLongTermAverageLux < mDarkeningLuxThreshold) { - // The ambient environment appears to be darkening. - if (mDebounceLuxDirection >= 0) { - mDebounceLuxDirection = -1; - mDebounceLuxTime = time; - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for " - + DARKENING_LIGHT_DEBOUNCE + " ms: " - + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - } - long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE; - if (time < debounceTime) { - mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime); - return; - } - // Be conservative about reducing the brightness, only reduce it a little bit - // at a time to avoid having to bump it up again soon. - setAmbientLux(Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux)); - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Darkened: " - + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - updateAutoBrightness(true); - } else if (mDebounceLuxDirection != 0) { - // No change or change is within the hysteresis thresholds. - mDebounceLuxDirection = 0; - mDebounceLuxTime = time; - if (DEBUG) { - Slog.d(TAG, "updateAmbientLux: Canceled debounce: " - + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold - + ", mDarkeningLuxThreshold=" + mDarkeningLuxThreshold - + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux - + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux - + ", mAmbientLux=" + mAmbientLux); - } - } - - // Now that we've done all of that, we haven't yet posted a debounce - // message. So consider the case where current lux is beyond the - // threshold. It's possible that the light sensor may not report values - // if the light level does not change, so we need to occasionally - // synthesize sensor readings in order to make sure the brightness is - // adjusted accordingly. Note these thresholds may have changed since - // we entered the function because we called setAmbientLux and - // updateAutoBrightness along the way. - if (mLastObservedLux > mBrighteningLuxThreshold - || mLastObservedLux < mDarkeningLuxThreshold) { - mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, - time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS); - } - } - - private void debounceLightSensor() { - if (mLightSensorEnabled) { - long time = SystemClock.uptimeMillis(); - if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) { - if (DEBUG) { - Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement " - + "after " + (time - mLastObservedLuxTime) + " ms."); - } - applyLightSensorMeasurement(time, mLastObservedLux); - } - updateAmbientLux(time); - } - } - - private void updateAutoBrightness(boolean sendUpdate) { - if (!mAmbientLuxValid) { - return; - } - - float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux); - float gamma = 1.0f; - - if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT - && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) { - final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA, - Math.min(1.0f, Math.max(-1.0f, - -mPowerRequest.screenAutoBrightnessAdjustment))); - gamma *= adjGamma; - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma); - } - } - - if (USE_TWILIGHT_ADJUSTMENT) { - TwilightState state = mTwilight.getCurrentState(); - if (state != null && state.isNight()) { - final long now = System.currentTimeMillis(); - final float earlyGamma = - getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise()); - final float lateGamma = - getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise()); - gamma *= earlyGamma * lateGamma; - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma - + ", lateGamma=" + lateGamma); - } - } - } - - if (gamma != 1.0f) { - final float in = value; - value = FloatMath.pow(value, gamma); - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma - + ", in=" + in + ", out=" + value); - } - } - - int newScreenAutoBrightness = clampScreenBrightness( - Math.round(value * PowerManager.BRIGHTNESS_ON)); - if (mScreenAutoBrightness != newScreenAutoBrightness) { - if (DEBUG) { - Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness=" - + mScreenAutoBrightness + ", newScreenAutoBrightness=" - + newScreenAutoBrightness); - } - - mScreenAutoBrightness = newScreenAutoBrightness; - mLastScreenAutoBrightnessGamma = gamma; - if (sendUpdate) { - sendUpdatePowerState(); - } - } - } - - private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) { - if (lastSunset < 0 || nextSunrise < 0 - || now < lastSunset || now > nextSunrise) { - return 1.0f; - } - - if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) { - return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA, - (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME); - } - - if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) { - return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA, - (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME); - } - - return TWILIGHT_ADJUSTMENT_MAX_GAMMA; - } - - private static float lerp(float x, float y, float alpha) { - return x + (y - x) * alpha; - } - - private void sendOnStateChangedWithWakelock() { - mDisplaySuspendBlocker.acquire(); - mCallbackHandler.post(mOnStateChangedRunnable); - } - - private final Runnable mOnStateChangedRunnable = new Runnable() { - @Override - public void run() { - mCallbacks.onStateChanged(); - mDisplaySuspendBlocker.release(); - } - }; - - private void sendOnProximityPositiveWithWakelock() { - mDisplaySuspendBlocker.acquire(); - mCallbackHandler.post(mOnProximityPositiveRunnable); - } - - private final Runnable mOnProximityPositiveRunnable = new Runnable() { - @Override - public void run() { - mCallbacks.onProximityPositive(); - mDisplaySuspendBlocker.release(); - } - }; - - private void sendOnProximityNegativeWithWakelock() { - mDisplaySuspendBlocker.acquire(); - mCallbackHandler.post(mOnProximityNegativeRunnable); - } - - private final Runnable mOnProximityNegativeRunnable = new Runnable() { - @Override - public void run() { - mCallbacks.onProximityNegative(); - mDisplaySuspendBlocker.release(); - } - }; - - public void dump(final PrintWriter pw) { - synchronized (mLock) { - pw.println(); - pw.println("Display Controller Locked State:"); - pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked); - pw.println(" mPendingRequestLocked=" + mPendingRequestLocked); - pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked); - pw.println(" mPendingWaitForNegativeProximityLocked=" - + mPendingWaitForNegativeProximityLocked); - pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked); - } - - pw.println(); - pw.println("Display Controller Configuration:"); - pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); - pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); - pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); - pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); - pw.println(" mUseSoftwareAutoBrightnessConfig=" - + mUseSoftwareAutoBrightnessConfig); - pw.println(" mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline); - pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig); - - mHandler.runWithScissors(new Runnable() { - @Override - public void run() { - dumpLocal(pw); - } - }, 1000); - } - - private void dumpLocal(PrintWriter pw) { - pw.println(); - pw.println("Display Controller Thread State:"); - pw.println(" mPowerRequest=" + mPowerRequest); - pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); - - pw.println(" mProximitySensor=" + mProximitySensor); - pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); - pw.println(" mProximityThreshold=" + mProximityThreshold); - pw.println(" mProximity=" + proximityToString(mProximity)); - pw.println(" mPendingProximity=" + proximityToString(mPendingProximity)); - pw.println(" mPendingProximityDebounceTime=" - + TimeUtils.formatUptime(mPendingProximityDebounceTime)); - pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity); - - pw.println(" mLightSensor=" + mLightSensor); - pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); - pw.println(" mLightSensorEnableTime=" - + TimeUtils.formatUptime(mLightSensorEnableTime)); - pw.println(" mAmbientLux=" + mAmbientLux); - pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); - pw.println(" mLastObservedLux=" + mLastObservedLux); - pw.println(" mLastObservedLuxTime=" - + TimeUtils.formatUptime(mLastObservedLuxTime)); - pw.println(" mRecentLightSamples=" + mRecentLightSamples); - pw.println(" mRecentShortTermAverageLux=" + mRecentShortTermAverageLux); - pw.println(" mRecentLongTermAverageLux=" + mRecentLongTermAverageLux); - pw.println(" mDebounceLuxDirection=" + mDebounceLuxDirection); - pw.println(" mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime)); - pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness); - pw.println(" mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness); - pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma); - pw.println(" mTwilight.getCurrentState()=" + mTwilight.getCurrentState()); - - if (mElectronBeamOnAnimator != null) { - pw.println(" mElectronBeamOnAnimator.isStarted()=" + - mElectronBeamOnAnimator.isStarted()); - } - if (mElectronBeamOffAnimator != null) { - pw.println(" mElectronBeamOffAnimator.isStarted()=" + - mElectronBeamOffAnimator.isStarted()); - } - - if (mPowerState != null) { - mPowerState.dump(pw); - } - } - - private static String proximityToString(int state) { - switch (state) { - case PROXIMITY_UNKNOWN: - return "Unknown"; - case PROXIMITY_NEGATIVE: - return "Negative"; - case PROXIMITY_POSITIVE: - return "Positive"; - default: - return Integer.toString(state); - } - } - - /** - * Asynchronous callbacks from the power controller to the power manager service. - */ - public interface Callbacks { - void onStateChanged(); - void onProximityPositive(); - void onProximityNegative(); - } - - private final class DisplayControllerHandler extends Handler { - public DisplayControllerHandler(Looper looper) { - super(looper, null, true /*async*/); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_POWER_STATE: - updatePowerState(); - break; - - case MSG_PROXIMITY_SENSOR_DEBOUNCED: - debounceProximitySensor(); - break; - - case MSG_LIGHT_SENSOR_DEBOUNCED: - debounceLightSensor(); - break; - } - } - } - - private final SensorEventListener mProximitySensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - if (mProximitySensorEnabled) { - final long time = SystemClock.uptimeMillis(); - final float distance = event.values[0]; - boolean positive = distance >= 0.0f && distance < mProximityThreshold; - handleProximitySensorEvent(time, positive); - } - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // Not used. - } - }; - - private final SensorEventListener mLightSensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - if (mLightSensorEnabled) { - final long time = SystemClock.uptimeMillis(); - final float lux = event.values[0]; - handleLightSensorEvent(time, lux); - } - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // Not used. - } - }; - - private final TwilightListener mTwilightListener = new TwilightListener() { - @Override - public void onTwilightStateChanged() { - mTwilightChanged = true; - updatePowerState(); - } - }; -} diff --git a/services/core/java/com/android/server/power/DisplayPowerRequest.java b/services/core/java/com/android/server/power/DisplayPowerRequest.java deleted file mode 100644 index 6061a40..0000000 --- a/services/core/java/com/android/server/power/DisplayPowerRequest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -import android.os.PowerManager; - -/** - * Describes the requested power state of the display. - * - * This object is intended to describe the general characteristics of the - * power state, such as whether the screen should be on or off and the current - * brightness controls leaving the {@link DisplayPowerController} to manage the - * details of how the transitions between states should occur. The goal is for - * the {@link PowerManagerService} to focus on the global power state and not - * have to micro-manage screen off animations, auto-brightness and other effects. - */ -final class DisplayPowerRequest { - public static final int SCREEN_STATE_OFF = 0; - public static final int SCREEN_STATE_DOZE = 1; - public static final int SCREEN_STATE_DIM = 2; - public static final int SCREEN_STATE_BRIGHT = 3; - - // The requested minimum screen power state: off, doze, dim or bright. - public int screenState; - - // If true, the proximity sensor overrides the screen state when an object is - // nearby, turning it off temporarily until the object is moved away. - public boolean useProximitySensor; - - // The desired screen brightness in the range 0 (minimum / off) to 255 (brightest). - // The display power controller may choose to clamp the brightness. - // When auto-brightness is enabled, this field should specify a nominal default - // value to use while waiting for the light sensor to report enough data. - public int screenBrightness; - - // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter). - public float screenAutoBrightnessAdjustment; - - // If true, enables automatic brightness control. - public boolean useAutoBrightness; - - // If true, prevents the screen from completely turning on if it is currently off. - // The display does not enter a "ready" state if this flag is true and screen on is - // blocked. The window manager policy blocks screen on while it prepares the keyguard to - // prevent the user from seeing intermediate updates. - // - // Technically, we may not block the screen itself from turning on (because that introduces - // extra unnecessary latency) but we do prevent content on screen from becoming - // visible to the user. - public boolean blockScreenOn; - - public DisplayPowerRequest() { - screenState = SCREEN_STATE_BRIGHT; - useProximitySensor = false; - screenBrightness = PowerManager.BRIGHTNESS_ON; - screenAutoBrightnessAdjustment = 0.0f; - useAutoBrightness = false; - blockScreenOn = false; - } - - public DisplayPowerRequest(DisplayPowerRequest other) { - copyFrom(other); - } - - // Returns true if we want the screen on in any mode, including doze. - public boolean wantScreenOnAny() { - return screenState != SCREEN_STATE_OFF; - } - - // Returns true if we want the screen on in a normal mode, excluding doze. - // This is usually what we want to tell the rest of the system. For compatibility - // reasons, we pretend the screen is off when dozing. - public boolean wantScreenOnNormal() { - return screenState == SCREEN_STATE_DIM || screenState == SCREEN_STATE_BRIGHT; - } - - public boolean wantLightSensorEnabled() { - // Specifically, we don't want the light sensor while dozing. - return useAutoBrightness && wantScreenOnNormal(); - } - - public void copyFrom(DisplayPowerRequest other) { - screenState = other.screenState; - useProximitySensor = other.useProximitySensor; - screenBrightness = other.screenBrightness; - screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment; - useAutoBrightness = other.useAutoBrightness; - blockScreenOn = other.blockScreenOn; - } - - @Override - public boolean equals(Object o) { - return o instanceof DisplayPowerRequest - && equals((DisplayPowerRequest)o); - } - - public boolean equals(DisplayPowerRequest other) { - return other != null - && screenState == other.screenState - && useProximitySensor == other.useProximitySensor - && screenBrightness == other.screenBrightness - && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment - && useAutoBrightness == other.useAutoBrightness - && blockScreenOn == other.blockScreenOn; - } - - @Override - public int hashCode() { - return 0; // don't care - } - - @Override - public String toString() { - return "screenState=" + screenState - + ", useProximitySensor=" + useProximitySensor - + ", screenBrightness=" + screenBrightness - + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment - + ", useAutoBrightness=" + useAutoBrightness - + ", blockScreenOn=" + blockScreenOn; - } -} diff --git a/services/core/java/com/android/server/power/DisplayPowerState.java b/services/core/java/com/android/server/power/DisplayPowerState.java deleted file mode 100644 index 8e331ad..0000000 --- a/services/core/java/com/android/server/power/DisplayPowerState.java +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -import com.android.server.lights.Light; - -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; -import android.os.PowerManager; -import android.util.FloatProperty; -import android.util.IntProperty; -import android.util.Slog; -import android.view.Choreographer; - -import java.io.PrintWriter; - -/** - * Controls the display power state. - * <p> - * This component is similar in nature to a {@link View} except that it describes - * the properties of a display. When properties are changed, the component - * invalidates itself and posts a callback to apply the changes in a consistent order. - * This mechanism enables multiple properties of the display power state to be animated - * together smoothly by the animation framework. Some of the work to blank or unblank - * the display is done on a separate thread to avoid blocking the looper. - * </p><p> - * This component must only be created or accessed by the {@link Looper} thread - * that belongs to the {@link DisplayPowerController}. - * </p><p> - * We don't need to worry about holding a suspend blocker here because the - * {@link PowerManagerService} does that for us whenever there is a change - * in progress. - * </p> - */ -final class DisplayPowerState { - private static final String TAG = "DisplayPowerState"; - - private static boolean DEBUG = false; - - private final Handler mHandler; - private final Choreographer mChoreographer; - private final ElectronBeam mElectronBeam; - private final DisplayBlanker mDisplayBlanker; - private final Light mBacklight; - private final PhotonicModulator mPhotonicModulator; - - private boolean mScreenOn; - private int mScreenBrightness; - private boolean mScreenReady; - private boolean mScreenUpdatePending; - - private boolean mElectronBeamPrepared; - private float mElectronBeamLevel; - private boolean mElectronBeamReady; - private boolean mElectronBeamDrawPending; - - private Runnable mCleanListener; - - public DisplayPowerState(ElectronBeam electronBean, - DisplayBlanker displayBlanker, Light backlight) { - mHandler = new Handler(true /*async*/); - mChoreographer = Choreographer.getInstance(); - mElectronBeam = electronBean; - mDisplayBlanker = displayBlanker; - mBacklight = backlight; - mPhotonicModulator = new PhotonicModulator(); - - // At boot time, we know that the screen is on and the electron beam - // animation is not playing. We don't know the screen's brightness though, - // so prepare to set it to a known state when the state is next applied. - // Although we set the brightness to full on here, the display power controller - // will reset the brightness to a new level immediately before the changes - // actually have a chance to be applied. - mScreenOn = true; - mScreenBrightness = PowerManager.BRIGHTNESS_ON; - scheduleScreenUpdate(); - - mElectronBeamPrepared = false; - mElectronBeamLevel = 1.0f; - mElectronBeamReady = true; - } - - public static final FloatProperty<DisplayPowerState> ELECTRON_BEAM_LEVEL = - new FloatProperty<DisplayPowerState>("electronBeamLevel") { - @Override - public void setValue(DisplayPowerState object, float value) { - object.setElectronBeamLevel(value); - } - - @Override - public Float get(DisplayPowerState object) { - return object.getElectronBeamLevel(); - } - }; - - public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS = - new IntProperty<DisplayPowerState>("screenBrightness") { - @Override - public void setValue(DisplayPowerState object, int value) { - object.setScreenBrightness(value); - } - - @Override - public Integer get(DisplayPowerState object) { - return object.getScreenBrightness(); - } - }; - - /** - * Sets whether the screen is on or off. - */ - public void setScreenOn(boolean on) { - if (mScreenOn != on) { - if (DEBUG) { - Slog.d(TAG, "setScreenOn: on=" + on); - } - - mScreenOn = on; - mScreenReady = false; - scheduleScreenUpdate(); - } - } - - /** - * Returns true if the screen is on. - */ - public boolean isScreenOn() { - return mScreenOn; - } - - /** - * Sets the display brightness. - * - * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest). - */ - public void setScreenBrightness(int brightness) { - if (mScreenBrightness != brightness) { - if (DEBUG) { - Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); - } - - mScreenBrightness = brightness; - if (mScreenOn) { - mScreenReady = false; - scheduleScreenUpdate(); - } - } - } - - /** - * Gets the screen brightness. - */ - public int getScreenBrightness() { - return mScreenBrightness; - } - - /** - * Prepares the electron beam to turn on or off. - * This method should be called before starting an animation because it - * can take a fair amount of time to prepare the electron beam surface. - * - * @param mode The electron beam animation mode to prepare. - * @return True if the electron beam was prepared. - */ - public boolean prepareElectronBeam(int mode) { - if (!mElectronBeam.prepare(mode)) { - mElectronBeamPrepared = false; - mElectronBeamReady = true; - return false; - } - - mElectronBeamPrepared = true; - mElectronBeamReady = false; - scheduleElectronBeamDraw(); - return true; - } - - /** - * Dismisses the electron beam surface. - */ - public void dismissElectronBeam() { - mElectronBeam.dismiss(); - mElectronBeamPrepared = false; - mElectronBeamReady = true; - } - - /** - * Sets the level of the electron beam steering current. - * - * The display is blanked when the level is 0.0. In normal use, the electron - * beam should have a value of 1.0. The electron beam is unstable in between - * these states and the picture quality may be compromised. For best effect, - * the electron beam should be warmed up or cooled off slowly. - * - * Warning: Electron beam emits harmful radiation. Avoid direct exposure to - * skin or eyes. - * - * @param level The level, ranges from 0.0 (full off) to 1.0 (full on). - */ - public void setElectronBeamLevel(float level) { - if (mElectronBeamLevel != level) { - if (DEBUG) { - Slog.d(TAG, "setElectronBeamLevel: level=" + level); - } - - mElectronBeamLevel = level; - if (mScreenOn) { - mScreenReady = false; - scheduleScreenUpdate(); // update backlight brightness - } - if (mElectronBeamPrepared) { - mElectronBeamReady = false; - scheduleElectronBeamDraw(); - } - } - } - - /** - * Gets the level of the electron beam steering current. - */ - public float getElectronBeamLevel() { - return mElectronBeamLevel; - } - - /** - * Returns true if no properties have been invalidated. - * Otherwise, returns false and promises to invoke the specified listener - * when the properties have all been applied. - * The listener always overrides any previously set listener. - */ - public boolean waitUntilClean(Runnable listener) { - if (!mScreenReady || !mElectronBeamReady) { - mCleanListener = listener; - return false; - } else { - mCleanListener = null; - return true; - } - } - - public void dump(PrintWriter pw) { - pw.println(); - pw.println("Display Power State:"); - pw.println(" mScreenOn=" + mScreenOn); - pw.println(" mScreenBrightness=" + mScreenBrightness); - pw.println(" mScreenReady=" + mScreenReady); - pw.println(" mScreenUpdatePending=" + mScreenUpdatePending); - pw.println(" mElectronBeamPrepared=" + mElectronBeamPrepared); - pw.println(" mElectronBeamLevel=" + mElectronBeamLevel); - pw.println(" mElectronBeamReady=" + mElectronBeamReady); - pw.println(" mElectronBeamDrawPending=" + mElectronBeamDrawPending); - - mPhotonicModulator.dump(pw); - mElectronBeam.dump(pw); - } - - private void scheduleScreenUpdate() { - if (!mScreenUpdatePending) { - mScreenUpdatePending = true; - postScreenUpdateThreadSafe(); - } - } - - private void postScreenUpdateThreadSafe() { - mHandler.removeCallbacks(mScreenUpdateRunnable); - mHandler.post(mScreenUpdateRunnable); - } - - private void scheduleElectronBeamDraw() { - if (!mElectronBeamDrawPending) { - mElectronBeamDrawPending = true; - mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, - mElectronBeamDrawRunnable, null); - } - } - - private void invokeCleanListenerIfNeeded() { - final Runnable listener = mCleanListener; - if (listener != null && mScreenReady && mElectronBeamReady) { - mCleanListener = null; - listener.run(); - } - } - - private final Runnable mScreenUpdateRunnable = new Runnable() { - @Override - public void run() { - mScreenUpdatePending = false; - - int brightness = mScreenOn && mElectronBeamLevel > 0f ? mScreenBrightness : 0; - if (mPhotonicModulator.setState(mScreenOn, brightness)) { - if (DEBUG) { - Slog.d(TAG, "Screen ready"); - } - mScreenReady = true; - invokeCleanListenerIfNeeded(); - } else { - if (DEBUG) { - Slog.d(TAG, "Screen not ready"); - } - } - } - }; - - private final Runnable mElectronBeamDrawRunnable = new Runnable() { - @Override - public void run() { - mElectronBeamDrawPending = false; - - if (mElectronBeamPrepared) { - mElectronBeam.draw(mElectronBeamLevel); - } - - mElectronBeamReady = true; - invokeCleanListenerIfNeeded(); - } - }; - - /** - * Updates the state of the screen and backlight asynchronously on a separate thread. - */ - private final class PhotonicModulator { - private static final boolean INITIAL_SCREEN_ON = false; // unknown, assume off - private static final int INITIAL_BACKLIGHT = -1; // unknown - - private final Object mLock = new Object(); - - private boolean mPendingOn = INITIAL_SCREEN_ON; - private int mPendingBacklight = INITIAL_BACKLIGHT; - private boolean mActualOn = INITIAL_SCREEN_ON; - private int mActualBacklight = INITIAL_BACKLIGHT; - private boolean mChangeInProgress; - - public boolean setState(boolean on, int backlight) { - synchronized (mLock) { - if (on != mPendingOn || backlight != mPendingBacklight) { - if (DEBUG) { - Slog.d(TAG, "Requesting new screen state: on=" + on - + ", backlight=" + backlight); - } - - mPendingOn = on; - mPendingBacklight = backlight; - - if (!mChangeInProgress) { - mChangeInProgress = true; - AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); - } - } - return !mChangeInProgress; - } - } - - public void dump(PrintWriter pw) { - pw.println(); - pw.println("Photonic Modulator State:"); - pw.println(" mPendingOn=" + mPendingOn); - pw.println(" mPendingBacklight=" + mPendingBacklight); - pw.println(" mActualOn=" + mActualOn); - pw.println(" mActualBacklight=" + mActualBacklight); - pw.println(" mChangeInProgress=" + mChangeInProgress); - } - - private final Runnable mTask = new Runnable() { - @Override - public void run() { - // Apply pending changes until done. - for (;;) { - final boolean on; - final boolean onChanged; - final int backlight; - final boolean backlightChanged; - synchronized (mLock) { - on = mPendingOn; - onChanged = (on != mActualOn); - backlight = mPendingBacklight; - backlightChanged = (backlight != mActualBacklight); - if (!onChanged && !backlightChanged) { - mChangeInProgress = false; - break; - } - mActualOn = on; - mActualBacklight = backlight; - } - - if (DEBUG) { - Slog.d(TAG, "Updating screen state: on=" + on - + ", backlight=" + backlight); - } - if (onChanged && on) { - mDisplayBlanker.unblankAllDisplays(); - } - if (backlightChanged) { - mBacklight.setBrightness(backlight); - } - if (onChanged && !on) { - mDisplayBlanker.blankAllDisplays(); - } - } - - // Let the outer class know that all changes have been applied. - postScreenUpdateThreadSafe(); - } - }; - } -} diff --git a/services/core/java/com/android/server/power/ElectronBeam.java b/services/core/java/com/android/server/power/ElectronBeam.java deleted file mode 100644 index 64921d7..0000000 --- a/services/core/java/com/android/server/power/ElectronBeam.java +++ /dev/null @@ -1,736 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -import java.io.PrintWriter; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import android.graphics.PixelFormat; -import android.graphics.SurfaceTexture; -import android.hardware.display.DisplayManagerInternal; -import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; -import android.opengl.EGL14; -import android.opengl.EGLConfig; -import android.opengl.EGLContext; -import android.opengl.EGLDisplay; -import android.opengl.EGLSurface; -import android.opengl.GLES10; -import android.opengl.GLES11Ext; -import android.os.Looper; -import android.util.FloatMath; -import android.util.Slog; -import android.view.Display; -import android.view.DisplayInfo; -import android.view.Surface.OutOfResourcesException; -import android.view.Surface; -import android.view.SurfaceControl; -import android.view.SurfaceSession; - -import com.android.server.LocalServices; - -/** - * Bzzzoooop! *crackle* - * <p> - * Animates a screen transition from on to off or off to on by applying - * some GL transformations to a screenshot. - * </p><p> - * This component must only be created or accessed by the {@link Looper} thread - * that belongs to the {@link DisplayPowerController}. - * </p> - */ -final class ElectronBeam { - private static final String TAG = "ElectronBeam"; - - private static final boolean DEBUG = false; - - // The layer for the electron beam surface. - // This is currently hardcoded to be one layer above the boot animation. - private static final int ELECTRON_BEAM_LAYER = 0x40000001; - - // The relative proportion of the animation to spend performing - // the horizontal stretch effect. The remainder is spent performing - // the vertical stretch effect. - private static final float HSTRETCH_DURATION = 0.5f; - private static final float VSTRETCH_DURATION = 1.0f - HSTRETCH_DURATION; - - // The number of frames to draw when preparing the animation so that it will - // be ready to run smoothly. We use 3 frames because we are triple-buffered. - // See code for details. - private static final int DEJANK_FRAMES = 3; - - // Set to true when the animation context has been fully prepared. - private boolean mPrepared; - private int mMode; - - private final DisplayManagerInternal mDisplayManagerInternal; - private int mDisplayLayerStack; // layer stack associated with primary display - private int mDisplayWidth; // real width, not rotated - private int mDisplayHeight; // real height, not rotated - private SurfaceSession mSurfaceSession; - private SurfaceControl mSurfaceControl; - private Surface mSurface; - private NaturalSurfaceLayout mSurfaceLayout; - private EGLDisplay mEglDisplay; - private EGLConfig mEglConfig; - private EGLContext mEglContext; - private EGLSurface mEglSurface; - private boolean mSurfaceVisible; - private float mSurfaceAlpha; - - // Texture names. We only use one texture, which contains the screenshot. - private final int[] mTexNames = new int[1]; - private boolean mTexNamesGenerated; - private final float mTexMatrix[] = new float[16]; - - // Vertex and corresponding texture coordinates. - // We have 4 2D vertices, so 8 elements. The vertices form a quad. - private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8); - private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8); - - /** - * Animates an electron beam warming up. - */ - public static final int MODE_WARM_UP = 0; - - /** - * Animates an electron beam shutting off. - */ - public static final int MODE_COOL_DOWN = 1; - - /** - * Animates a simple dim layer to fade the contents of the screen in or out progressively. - */ - public static final int MODE_FADE = 2; - - - public ElectronBeam() { - mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); - } - - /** - * Warms up the electron beam in preparation for turning on or off. - * This method prepares a GL context, and captures a screen shot. - * - * @param mode The desired mode for the upcoming animation. - * @return True if the electron beam is ready, false if it is uncontrollable. - */ - public boolean prepare(int mode) { - if (DEBUG) { - Slog.d(TAG, "prepare: mode=" + mode); - } - - mMode = mode; - - // Get the display size and layer stack. - // This is not expected to change while the electron beam surface is showing. - DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY); - mDisplayLayerStack = displayInfo.layerStack; - mDisplayWidth = displayInfo.getNaturalWidth(); - mDisplayHeight = displayInfo.getNaturalHeight(); - - // Prepare the surface for drawing. - if (!tryPrepare()) { - dismiss(); - return false; - } - - // Done. - mPrepared = true; - - // Dejanking optimization. - // Some GL drivers can introduce a lot of lag in the first few frames as they - // initialize their state and allocate graphics buffers for rendering. - // Work around this problem by rendering the first frame of the animation a few - // times. The rest of the animation should run smoothly thereafter. - // The frames we draw here aren't visible because we are essentially just - // painting the screenshot as-is. - if (mode == MODE_COOL_DOWN) { - for (int i = 0; i < DEJANK_FRAMES; i++) { - draw(1.0f); - } - } - return true; - } - - private boolean tryPrepare() { - if (createSurface()) { - if (mMode == MODE_FADE) { - return true; - } - return createEglContext() - && createEglSurface() - && captureScreenshotTextureAndSetViewport(); - } - return false; - } - - /** - * Dismisses the electron beam animation surface and cleans up. - * - * To prevent stray photons from leaking out after the electron beam has been - * turned off, it is a good idea to defer dismissing the animation until the - * electron beam has been turned back on fully. - */ - public void dismiss() { - if (DEBUG) { - Slog.d(TAG, "dismiss"); - } - - destroyScreenshotTexture(); - destroyEglSurface(); - destroySurface(); - mPrepared = false; - } - - /** - * Draws an animation frame showing the electron beam activated at the - * specified level. - * - * @param level The electron beam level. - * @return True if successful. - */ - public boolean draw(float level) { - if (DEBUG) { - Slog.d(TAG, "drawFrame: level=" + level); - } - - if (!mPrepared) { - return false; - } - - if (mMode == MODE_FADE) { - return showSurface(1.0f - level); - } - - if (!attachEglContext()) { - return false; - } - try { - // Clear frame to solid black. - GLES10.glClearColor(0f, 0f, 0f, 1f); - GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT); - - // Draw the frame. - if (level < HSTRETCH_DURATION) { - drawHStretch(1.0f - (level / HSTRETCH_DURATION)); - } else { - drawVStretch(1.0f - ((level - HSTRETCH_DURATION) / VSTRETCH_DURATION)); - } - if (checkGlErrors("drawFrame")) { - return false; - } - - EGL14.eglSwapBuffers(mEglDisplay, mEglSurface); - } finally { - detachEglContext(); - } - return showSurface(1.0f); - } - - /** - * Draws a frame where the content of the electron beam is collapsing inwards upon - * itself vertically with red / green / blue channels dispersing and eventually - * merging down to a single horizontal line. - * - * @param stretch The stretch factor. 0.0 is no collapse, 1.0 is full collapse. - */ - private void drawVStretch(float stretch) { - // compute interpolation scale factors for each color channel - final float ar = scurve(stretch, 7.5f); - final float ag = scurve(stretch, 8.0f); - final float ab = scurve(stretch, 8.5f); - if (DEBUG) { - Slog.d(TAG, "drawVStretch: stretch=" + stretch - + ", ar=" + ar + ", ag=" + ag + ", ab=" + ab); - } - - // set blending - GLES10.glBlendFunc(GLES10.GL_ONE, GLES10.GL_ONE); - GLES10.glEnable(GLES10.GL_BLEND); - - // bind vertex buffer - GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); - GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); - - // set-up texturing - GLES10.glDisable(GLES10.GL_TEXTURE_2D); - GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); - - // bind texture and set blending for drawing planes - GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]); - GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE, - mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE); - GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, - GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR); - GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, - GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR); - GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, - GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE); - GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, - GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE); - GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); - GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer); - GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); - - // draw the red plane - setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ar); - GLES10.glColorMask(true, false, false, true); - GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); - - // draw the green plane - setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag); - GLES10.glColorMask(false, true, false, true); - GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); - - // draw the blue plane - setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ab); - GLES10.glColorMask(false, false, true, true); - GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); - - // clean up after drawing planes - GLES10.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); - GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); - GLES10.glColorMask(true, true, true, true); - - // draw the white highlight (we use the last vertices) - if (mMode == MODE_COOL_DOWN) { - GLES10.glColor4f(ag, ag, ag, 1.0f); - GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); - } - - // clean up - GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY); - GLES10.glDisable(GLES10.GL_BLEND); - } - - /** - * Draws a frame where the electron beam has been stretched out into - * a thin white horizontal line that fades as it collapses inwards. - * - * @param stretch The stretch factor. 0.0 is maximum stretch / no fade, - * 1.0 is collapsed / maximum fade. - */ - private void drawHStretch(float stretch) { - // compute interpolation scale factor - final float ag = scurve(stretch, 8.0f); - if (DEBUG) { - Slog.d(TAG, "drawHStretch: stretch=" + stretch + ", ag=" + ag); - } - - if (stretch < 1.0f) { - // bind vertex buffer - GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); - GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); - - // draw narrow fading white line - setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag); - GLES10.glColor4f(1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f); - GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); - - // clean up - GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY); - } - } - - private static void setVStretchQuad(FloatBuffer vtx, float dw, float dh, float a) { - final float w = dw + (dw * a); - final float h = dh - (dh * a); - final float x = (dw - w) * 0.5f; - final float y = (dh - h) * 0.5f; - setQuad(vtx, x, y, w, h); - } - - private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) { - final float w = 2 * dw * (1.0f - a); - final float h = 1.0f; - final float x = (dw - w) * 0.5f; - final float y = (dh - h) * 0.5f; - setQuad(vtx, x, y, w, h); - } - - private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) { - if (DEBUG) { - Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h); - } - vtx.put(0, x); - vtx.put(1, y); - vtx.put(2, x); - vtx.put(3, y + h); - vtx.put(4, x + w); - vtx.put(5, y + h); - vtx.put(6, x + w); - vtx.put(7, y); - } - - private boolean captureScreenshotTextureAndSetViewport() { - if (!attachEglContext()) { - return false; - } - try { - if (!mTexNamesGenerated) { - GLES10.glGenTextures(1, mTexNames, 0); - if (checkGlErrors("glGenTextures")) { - return false; - } - mTexNamesGenerated = true; - } - - final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); - final Surface s = new Surface(st); - try { - SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay( - SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s); - } finally { - s.release(); - } - - st.updateTexImage(); - st.getTransformMatrix(mTexMatrix); - - // Set up texture coordinates for a quad. - // We might need to change this if the texture ends up being - // a different size from the display for some reason. - mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f); - mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f); - mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f); - mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f); - - // Set up our viewport. - GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight); - GLES10.glMatrixMode(GLES10.GL_PROJECTION); - GLES10.glLoadIdentity(); - GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1); - GLES10.glMatrixMode(GLES10.GL_MODELVIEW); - GLES10.glLoadIdentity(); - GLES10.glMatrixMode(GLES10.GL_TEXTURE); - GLES10.glLoadIdentity(); - GLES10.glLoadMatrixf(mTexMatrix, 0); - } finally { - detachEglContext(); - } - return true; - } - - private void destroyScreenshotTexture() { - if (mTexNamesGenerated) { - mTexNamesGenerated = false; - if (attachEglContext()) { - try { - GLES10.glDeleteTextures(1, mTexNames, 0); - checkGlErrors("glDeleteTextures"); - } finally { - detachEglContext(); - } - } - } - } - - private boolean createEglContext() { - if (mEglDisplay == null) { - mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); - if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { - logEglError("eglGetDisplay"); - return false; - } - - int[] version = new int[2]; - if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) { - mEglDisplay = null; - logEglError("eglInitialize"); - return false; - } - } - - if (mEglConfig == null) { - int[] eglConfigAttribList = new int[] { - EGL14.EGL_RED_SIZE, 8, - EGL14.EGL_GREEN_SIZE, 8, - EGL14.EGL_BLUE_SIZE, 8, - EGL14.EGL_ALPHA_SIZE, 8, - EGL14.EGL_NONE - }; - int[] numEglConfigs = new int[1]; - EGLConfig[] eglConfigs = new EGLConfig[1]; - if (!EGL14.eglChooseConfig(mEglDisplay, eglConfigAttribList, 0, - eglConfigs, 0, eglConfigs.length, numEglConfigs, 0)) { - logEglError("eglChooseConfig"); - return false; - } - mEglConfig = eglConfigs[0]; - } - - if (mEglContext == null) { - int[] eglContextAttribList = new int[] { - EGL14.EGL_NONE - }; - mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, - EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); - if (mEglContext == null) { - logEglError("eglCreateContext"); - return false; - } - } - return true; - } - - /* not used because it is too expensive to create / destroy contexts all of the time - private void destroyEglContext() { - if (mEglContext != null) { - if (!EGL14.eglDestroyContext(mEglDisplay, mEglContext)) { - logEglError("eglDestroyContext"); - } - mEglContext = null; - } - }*/ - - private boolean createSurface() { - if (mSurfaceSession == null) { - mSurfaceSession = new SurfaceSession(); - } - - SurfaceControl.openTransaction(); - try { - if (mSurfaceControl == null) { - try { - int flags; - if (mMode == MODE_FADE) { - flags = SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN; - } else { - flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; - } - mSurfaceControl = new SurfaceControl(mSurfaceSession, - "ElectronBeam", mDisplayWidth, mDisplayHeight, - PixelFormat.OPAQUE, flags); - } catch (OutOfResourcesException ex) { - Slog.e(TAG, "Unable to create surface.", ex); - return false; - } - } - - mSurfaceControl.setLayerStack(mDisplayLayerStack); - mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight); - mSurface = new Surface(); - mSurface.copyFrom(mSurfaceControl); - - mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mSurfaceControl); - mSurfaceLayout.onDisplayTransaction(); - } finally { - SurfaceControl.closeTransaction(); - } - return true; - } - - private boolean createEglSurface() { - if (mEglSurface == null) { - int[] eglSurfaceAttribList = new int[] { - EGL14.EGL_NONE - }; - // turn our SurfaceControl into a Surface - mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, - eglSurfaceAttribList, 0); - if (mEglSurface == null) { - logEglError("eglCreateWindowSurface"); - return false; - } - } - return true; - } - - private void destroyEglSurface() { - if (mEglSurface != null) { - if (!EGL14.eglDestroySurface(mEglDisplay, mEglSurface)) { - logEglError("eglDestroySurface"); - } - mEglSurface = null; - } - } - - private void destroySurface() { - if (mSurfaceControl != null) { - mSurfaceLayout.dispose(); - mSurfaceLayout = null; - SurfaceControl.openTransaction(); - try { - mSurfaceControl.destroy(); - mSurface.release(); - } finally { - SurfaceControl.closeTransaction(); - } - mSurfaceControl = null; - mSurfaceVisible = false; - mSurfaceAlpha = 0f; - } - } - - private boolean showSurface(float alpha) { - if (!mSurfaceVisible || mSurfaceAlpha != alpha) { - SurfaceControl.openTransaction(); - try { - mSurfaceControl.setLayer(ELECTRON_BEAM_LAYER); - mSurfaceControl.setAlpha(alpha); - mSurfaceControl.show(); - } finally { - SurfaceControl.closeTransaction(); - } - mSurfaceVisible = true; - mSurfaceAlpha = alpha; - } - return true; - } - - private boolean attachEglContext() { - if (mEglSurface == null) { - return false; - } - if (!EGL14.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - logEglError("eglMakeCurrent"); - return false; - } - return true; - } - - private void detachEglContext() { - if (mEglDisplay != null) { - EGL14.eglMakeCurrent(mEglDisplay, - EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); - } - } - - /** - * Interpolates a value in the range 0 .. 1 along a sigmoid curve - * yielding a result in the range 0 .. 1 scaled such that: - * scurve(0) == 0, scurve(0.5) == 0.5, scurve(1) == 1. - */ - private static float scurve(float value, float s) { - // A basic sigmoid has the form y = 1.0f / FloatMap.exp(-x * s). - // Here we take the input datum and shift it by 0.5 so that the - // domain spans the range -0.5 .. 0.5 instead of 0 .. 1. - final float x = value - 0.5f; - - // Next apply the sigmoid function to the scaled value - // which produces a value in the range 0 .. 1 so we subtract - // 0.5 to get a value in the range -0.5 .. 0.5 instead. - final float y = sigmoid(x, s) - 0.5f; - - // To obtain the desired boundary conditions we need to scale - // the result so that it fills a range of -1 .. 1. - final float v = sigmoid(0.5f, s) - 0.5f; - - // And finally remap the value back to a range of 0 .. 1. - return y / v * 0.5f + 0.5f; - } - - private static float sigmoid(float x, float s) { - return 1.0f / (1.0f + FloatMath.exp(-x * s)); - } - - private static FloatBuffer createNativeFloatBuffer(int size) { - ByteBuffer bb = ByteBuffer.allocateDirect(size * 4); - bb.order(ByteOrder.nativeOrder()); - return bb.asFloatBuffer(); - } - - private static void logEglError(String func) { - Slog.e(TAG, func + " failed: error " + EGL14.eglGetError(), new Throwable()); - } - - private static boolean checkGlErrors(String func) { - return checkGlErrors(func, true); - } - - private static boolean checkGlErrors(String func, boolean log) { - boolean hadError = false; - int error; - while ((error = GLES10.glGetError()) != GLES10.GL_NO_ERROR) { - if (log) { - Slog.e(TAG, func + " failed: error " + error, new Throwable()); - } - hadError = true; - } - return hadError; - } - - public void dump(PrintWriter pw) { - pw.println(); - pw.println("Electron Beam State:"); - pw.println(" mPrepared=" + mPrepared); - pw.println(" mMode=" + mMode); - pw.println(" mDisplayLayerStack=" + mDisplayLayerStack); - pw.println(" mDisplayWidth=" + mDisplayWidth); - pw.println(" mDisplayHeight=" + mDisplayHeight); - pw.println(" mSurfaceVisible=" + mSurfaceVisible); - pw.println(" mSurfaceAlpha=" + mSurfaceAlpha); - } - - /** - * Keeps a surface aligned with the natural orientation of the device. - * Updates the position and transformation of the matrix whenever the display - * is rotated. This is a little tricky because the display transaction - * callback can be invoked on any thread, not necessarily the thread that - * owns the electron beam. - */ - private static final class NaturalSurfaceLayout implements DisplayTransactionListener { - private final DisplayManagerInternal mDisplayManagerInternal; - private SurfaceControl mSurfaceControl; - - public NaturalSurfaceLayout(DisplayManagerInternal displayManagerInternal, - SurfaceControl surfaceControl) { - mDisplayManagerInternal = displayManagerInternal; - mSurfaceControl = surfaceControl; - mDisplayManagerInternal.registerDisplayTransactionListener(this); - } - - public void dispose() { - synchronized (this) { - mSurfaceControl = null; - } - mDisplayManagerInternal.unregisterDisplayTransactionListener(this); - } - - @Override - public void onDisplayTransaction() { - synchronized (this) { - if (mSurfaceControl == null) { - return; - } - - DisplayInfo displayInfo = - mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY); - switch (displayInfo.rotation) { - case Surface.ROTATION_0: - mSurfaceControl.setPosition(0, 0); - mSurfaceControl.setMatrix(1, 0, 0, 1); - break; - case Surface.ROTATION_90: - mSurfaceControl.setPosition(0, displayInfo.logicalHeight); - mSurfaceControl.setMatrix(0, -1, 1, 0); - break; - case Surface.ROTATION_180: - mSurfaceControl.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight); - mSurfaceControl.setMatrix(-1, 0, 0, -1); - break; - case Surface.ROTATION_270: - mSurfaceControl.setPosition(displayInfo.logicalWidth, 0); - mSurfaceControl.setMatrix(0, 1, -1, 0); - break; - } - } - } - } -} diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 264e2e9..c5a71ec 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -189,51 +189,6 @@ final class Notifier { } /** - * Called when the screen is turned on. - */ - public void onScreenOn() { - if (DEBUG) { - Slog.d(TAG, "onScreenOn"); - } - - try { - mBatteryStats.noteScreenOn(); - } catch (RemoteException ex) { - // Ignore - } - } - - /** - * Called when the screen is turned off. - */ - public void onScreenOff() { - if (DEBUG) { - Slog.d(TAG, "onScreenOff"); - } - - try { - mBatteryStats.noteScreenOff(); - } catch (RemoteException ex) { - // Ignore - } - } - - /** - * Called when the screen changes brightness. - */ - public void onScreenBrightness(int brightness) { - if (DEBUG) { - Slog.d(TAG, "onScreenBrightness: brightness=" + brightness); - } - - try { - mBatteryStats.noteScreenBrightness(brightness); - } catch (RemoteException ex) { - // Ignore - } - } - - /** * Called when the device is waking up from sleep and the * display is about to be turned on. */ diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index c251af1..6b2ca4c 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -24,7 +24,6 @@ import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.lights.Light; import com.android.server.lights.LightsManager; -import com.android.server.twilight.TwilightManager; import com.android.server.Watchdog; import android.Manifest; @@ -39,6 +38,7 @@ import android.database.ContentObserver; import android.hardware.SensorManager; import android.hardware.SystemSensorManager; import android.hardware.display.DisplayManagerInternal; +import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.net.Uri; import android.os.BatteryManager; import android.os.Binder; @@ -177,7 +177,6 @@ public final class PowerManagerService extends com.android.server.SystemService private PowerManagerHandler mHandler; private WindowManagerPolicy mPolicy; private Notifier mNotifier; - private DisplayPowerController mDisplayPowerController; private WirelessChargerDetector mWirelessChargerDetector; private SettingsObserver mSettingsObserver; private DreamManagerInternal mDreamManager; @@ -258,9 +257,6 @@ public final class PowerManagerService extends com.android.server.SystemService // screen is coming up. private final ScreenOnBlockerImpl mScreenOnBlocker; - // The display blanker used to turn the screen on or off. - private final DisplayBlankerImpl mDisplayBlanker; - // True if systemReady() has been called. private boolean mSystemReady; @@ -417,7 +413,6 @@ public final class PowerManagerService extends com.android.server.SystemService mHoldingDisplaySuspendBlocker = true; mScreenOnBlocker = new ScreenOnBlockerImpl(); - mDisplayBlanker = new DisplayBlankerImpl(); mWakefulness = WAKEFULNESS_AWAKE; } @@ -457,7 +452,7 @@ public final class PowerManagerService extends com.android.server.SystemService // into the activity manager to check permissions. Unfortunately the // activity manager is not running when the constructor is called, so we // have to defer setting the screen state until this point. - mDisplayBlanker.unblankAllDisplays(); + mDisplayPowerCallbacks.unblankAllDisplays(); } void setPolicy(WindowManagerPolicy policy) { @@ -484,20 +479,16 @@ public final class PowerManagerService extends com.android.server.SystemService mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mScreenOnBlocker, mPolicy); - // The display power controller runs on the power manager service's - // own handler thread to ensure timely operation. - mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(), - mContext, mNotifier, mLightsManager, - LocalServices.getService(TwilightManager.class), sensorManager, - mDisplaySuspendBlocker, mDisplayBlanker, - mDisplayPowerControllerCallbacks, mHandler); - mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); + // Initialize display power management. + mDisplayManagerInternal.initPowerManagement( + mDisplayPowerCallbacks, mHandler, sensorManager); + // Register for broadcasts from other components of the system. IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); @@ -810,7 +801,7 @@ public final class PowerManagerService extends com.android.server.SystemService return true; case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: - return mSystemReady && mDisplayPowerController.isProximitySensorAvailable(); + return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable(); default: return false; @@ -1633,7 +1624,7 @@ public final class PowerManagerService extends com.android.server.SystemService mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld(); - mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest, + mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); mRequestWaitForNegativeProximity = false; @@ -1675,8 +1666,10 @@ public final class PowerManagerService extends com.android.server.SystemService return DisplayPowerRequest.SCREEN_STATE_DIM; } - private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks = - new DisplayPowerController.Callbacks() { + private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks = + new DisplayManagerInternal.DisplayPowerCallbacks() { + private boolean mBlanked; + @Override public void onStateChanged() { synchronized (mLock) { @@ -1704,6 +1697,51 @@ public final class PowerManagerService extends com.android.server.SystemService updatePowerStateLocked(); } } + + @Override + public void acquireSuspendBlocker() { + mDisplaySuspendBlocker.acquire(); + } + + @Override + public void releaseSuspendBlocker() { + mDisplaySuspendBlocker.release(); + } + + @Override + public void blankAllDisplays() { + synchronized (this) { + mBlanked = true; + mDisplayManagerInternal.blankAllDisplaysFromPowerManager(); + if (!mDecoupleInteractiveModeFromDisplayConfig) { + setInteractiveModeLocked(false); + } + if (!mDecoupleAutoSuspendModeFromDisplayConfig) { + setAutoSuspendModeLocked(true); + } + } + } + + @Override + public void unblankAllDisplays() { + synchronized (this) { + if (!mDecoupleAutoSuspendModeFromDisplayConfig) { + setAutoSuspendModeLocked(false); + } + if (!mDecoupleInteractiveModeFromDisplayConfig) { + setInteractiveModeLocked(true); + } + mDisplayManagerInternal.unblankAllDisplaysFromPowerManager(); + mBlanked = false; + } + } + + @Override + public String toString() { + synchronized (this) { + return "blanked=" + mBlanked; + } + } }; private boolean shouldUseProximitySensorLocked() { @@ -2018,7 +2056,6 @@ public final class PowerManagerService extends com.android.server.SystemService private void dumpInternal(PrintWriter pw) { pw.println("POWER MANAGER (dumpsys power)\n"); - final DisplayPowerController dpc; final WirelessChargerDetector wcd; synchronized (mLock) { pw.println("Power Manager State:"); @@ -2123,16 +2160,11 @@ public final class PowerManagerService extends com.android.server.SystemService pw.println("Screen On Blocker: " + mScreenOnBlocker); pw.println(); - pw.println("Display Blanker: " + mDisplayBlanker); + pw.println("Display Power: " + mDisplayPowerCallbacks); - dpc = mDisplayPowerController; wcd = mWirelessChargerDetector; } - if (dpc != null) { - dpc.dump(pw); - } - if (wcd != null) { wcd.dump(pw); } @@ -2467,45 +2499,6 @@ public final class PowerManagerService extends com.android.server.SystemService } } - private final class DisplayBlankerImpl implements DisplayBlanker { - private boolean mBlanked; - - @Override - public void blankAllDisplays() { - synchronized (this) { - mBlanked = true; - mDisplayManagerInternal.blankAllDisplaysFromPowerManager(); - if (!mDecoupleInteractiveModeFromDisplayConfig) { - setInteractiveModeLocked(false); - } - if (!mDecoupleAutoSuspendModeFromDisplayConfig) { - setAutoSuspendModeLocked(true); - } - } - } - - @Override - public void unblankAllDisplays() { - synchronized (this) { - if (!mDecoupleAutoSuspendModeFromDisplayConfig) { - setAutoSuspendModeLocked(false); - } - if (!mDecoupleInteractiveModeFromDisplayConfig) { - setInteractiveModeLocked(true); - } - mDisplayManagerInternal.unblankAllDisplaysFromPowerManager(); - mBlanked = false; - } - } - - @Override - public String toString() { - synchronized (this) { - return "blanked=" + mBlanked; - } - } - } - private final class BinderService extends IPowerManager.Stub { @Override // Binder call public void acquireWakeLockWithUid(IBinder lock, int flags, String tag, @@ -2830,7 +2823,7 @@ public final class PowerManagerService extends com.android.server.SystemService * * @param adj The overridden brightness, or Float.NaN to disable the override. * - * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ + * @see android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ */ @Override // Binder call public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) { diff --git a/services/core/java/com/android/server/power/RampAnimator.java b/services/core/java/com/android/server/power/RampAnimator.java deleted file mode 100644 index 4a4f080..0000000 --- a/services/core/java/com/android/server/power/RampAnimator.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power; - -import android.animation.ValueAnimator; -import android.util.IntProperty; -import android.view.Choreographer; - -/** - * A custom animator that progressively updates a property value at - * a given variable rate until it reaches a particular target value. - */ -final class RampAnimator<T> { - private final T mObject; - private final IntProperty<T> mProperty; - private final Choreographer mChoreographer; - - private int mCurrentValue; - private int mTargetValue; - private int mRate; - - private boolean mAnimating; - private float mAnimatedValue; // higher precision copy of mCurrentValue - private long mLastFrameTimeNanos; - - private boolean mFirstTime = true; - - public RampAnimator(T object, IntProperty<T> property) { - mObject = object; - mProperty = property; - mChoreographer = Choreographer.getInstance(); - } - - /** - * Starts animating towards the specified value. - * - * If this is the first time the property is being set, the value jumps - * directly to the target. - * - * @param target The target value. - * @param rate The convergence rate, in units per second. - * @return True if the target differs from the previous target. - */ - public boolean animateTo(int target, int rate) { - // Immediately jump to the target the first time. - if (mFirstTime) { - mFirstTime = false; - mProperty.setValue(mObject, target); - mCurrentValue = target; - return true; - } - - // Adjust the rate based on the closest target. - // If a faster rate is specified, then use the new rate so that we converge - // more rapidly based on the new request. - // If a slower rate is specified, then use the new rate only if the current - // value is somewhere in between the new and the old target meaning that - // we will be ramping in a different direction to get there. - // Otherwise, continue at the previous rate. - if (!mAnimating - || rate > mRate - || (target <= mCurrentValue && mCurrentValue <= mTargetValue) - || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) { - mRate = rate; - } - - final boolean changed = (mTargetValue != target); - mTargetValue = target; - - // Start animating. - if (!mAnimating && target != mCurrentValue) { - mAnimating = true; - mAnimatedValue = mCurrentValue; - mLastFrameTimeNanos = System.nanoTime(); - postCallback(); - } - - return changed; - } - - private void postCallback() { - mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null); - } - - private final Runnable mCallback = new Runnable() { - @Override // Choreographer callback - public void run() { - final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); - final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos) - * 0.000000001f; - mLastFrameTimeNanos = frameTimeNanos; - - // Advance the animated value towards the target at the specified rate - // and clamp to the target. This gives us the new current value but - // we keep the animated value around to allow for fractional increments - // towards the target. - final float scale = ValueAnimator.getDurationScale(); - if (scale == 0) { - // Animation off. - mAnimatedValue = mTargetValue; - } else { - final float amount = timeDelta * mRate / scale; - if (mTargetValue > mCurrentValue) { - mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); - } else { - mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); - } - } - final int oldCurrentValue = mCurrentValue; - mCurrentValue = Math.round(mAnimatedValue); - - if (oldCurrentValue != mCurrentValue) { - mProperty.setValue(mObject, mCurrentValue); - } - - if (mTargetValue != mCurrentValue) { - postCallback(); - } else { - mAnimating = false; - } - } - }; -} |