Loading services/core/java/com/android/server/display/DisplayPowerController.java +46 −11 Original line number Diff line number Diff line Loading @@ -227,6 +227,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // turning off the screen. private boolean mPendingScreenOff; // True if we have unfinished business and are holding a suspend blocker. private boolean mUnfinishedBusiness; // The elapsed real time when the screen on was blocked. private long mScreenOnBlockStartRealTime; Loading Loading @@ -633,22 +636,42 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedLowPower = true; } // Animate the screen brightness when the screen is on. if (state != Display.STATE_OFF) { animateScreenBrightness(brightness, slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } // Animate the screen state change unless already animating. animateScreenStateChange(state, performScreenOffTransition); // Report whether the display is ready for use and all changes have been applied. if (mustNotify && mPendingScreenOnUnblocker == null // Animate the screen brightness when the screen is on or dozing. // Skip the animation when the screen is off or suspended. final int actualState = mPowerState.getScreenState(); if (actualState == Display.STATE_ON || actualState == Display.STATE_DOZE) { animateScreenBrightness(brightness, slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } else { animateScreenBrightness(brightness, 0); } // Determine whether the display is ready for use in the newly requested state. // Note that we do not wait for the brightness ramp animation to complete before // reporting the display is ready because we only need to ensure the screen is in the // right power state even as it continues to converge on the desired brightness. final boolean ready = mPendingScreenOnUnblocker == null && !mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted() && !mScreenBrightnessRampAnimator.isAnimating() && mPowerState.waitUntilClean(mCleanListener)) { && mPowerState.waitUntilClean(mCleanListener); final boolean finished = ready && !mScreenBrightnessRampAnimator.isAnimating(); // Grab a wake lock if we have unfinished business. if (!finished && !mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Unfinished business..."); } mCallbacks.acquireSuspendBlocker(); mUnfinishedBusiness = true; } // Notify the power manager when ready. if (ready && mustNotify) { // Send state change. synchronized (mLock) { if (!mPendingRequestChangedLocked) { mDisplayReadyLocked = true; Loading @@ -660,6 +683,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } sendOnStateChangedWithWakelock(); } // Release the wake lock when we have no unfinished business. if (finished && mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Finished business..."); } mUnfinishedBusiness = false; mCallbacks.releaseSuspendBlocker(); } } @Override Loading Loading @@ -723,6 +755,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void animateScreenBrightness(int target, int rate) { if (DEBUG) { Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { try { mBatteryStats.noteScreenBrightness(target); Loading services/core/java/com/android/server/display/DisplayPowerState.java +66 −62 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ final class DisplayPowerState { mBacklight = backlight; mColorFade = electronBeam; mPhotonicModulator = new PhotonicModulator(); mPhotonicModulator.start(); // 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, Loading Loading @@ -336,7 +337,7 @@ final class DisplayPowerState { /** * Updates the state of the screen and backlight asynchronously on a separate thread. */ private final class PhotonicModulator { private final class PhotonicModulator extends Thread { private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off private static final int INITIAL_BACKLIGHT = -1; // unknown Loading @@ -361,7 +362,7 @@ final class DisplayPowerState { if (!mChangeInProgress) { mChangeInProgress = true; AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); mLock.notifyAll(); } } return !mChangeInProgress; Loading @@ -369,6 +370,7 @@ final class DisplayPowerState { } public void dump(PrintWriter pw) { synchronized (mLock) { pw.println(); pw.println("Photonic Modulator State:"); pw.println(" mPendingState=" + Display.stateToString(mPendingState)); Loading @@ -377,12 +379,12 @@ final class DisplayPowerState { pw.println(" mActualBacklight=" + mActualBacklight); pw.println(" mChangeInProgress=" + mChangeInProgress); } } private final Runnable mTask = new Runnable() { @Override public void run() { // Apply pending changes until done. for (;;) { // Get pending change. final int state; final boolean stateChanged; final int backlight; Loading @@ -393,13 +395,19 @@ final class DisplayPowerState { backlight = mPendingBacklight; backlightChanged = (backlight != mActualBacklight); if (!stateChanged && !backlightChanged) { // All changed applied, notify outer class and wait for more. mChangeInProgress = false; break; postScreenUpdateThreadSafe(); try { mLock.wait(); } catch (InterruptedException ex) { } continue; } mActualState = state; mActualBacklight = backlight; } // Apply pending change. if (DEBUG) { Slog.d(TAG, "Updating screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); Loading @@ -415,9 +423,6 @@ final class DisplayPowerState { requestDisplayState(state); } } // Let the outer class know that all changes have been applied. postScreenUpdateThreadSafe(); } private void requestDisplayState(int state) { Loading @@ -438,6 +443,5 @@ final class DisplayPowerState { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }; } } services/core/java/com/android/server/display/RampAnimator.java +29 −13 Original line number Diff line number Diff line Loading @@ -50,21 +50,33 @@ final class RampAnimator<T> { /** * Starts animating towards the specified value. * * If this is the first time the property is being set, the value jumps * directly to the target. * If this is the first time the property is being set or if the rate is 0, * the value jumps directly to the target. * * @param target The target value. * @param rate The convergence rate, in units per second. * @param rate The convergence rate in units per second, or 0 to set the value immediately. * @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) { if (mFirstTime || rate <= 0) { if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mProperty.setValue(mObject, target); mRate = 0; mTargetValue = target; mCurrentValue = target; mProperty.setValue(mObject, target); if (mAnimating) { mAnimating = false; cancelAnimationCallback(); } if (mListener != null) { mListener.onAnimationEnd(); } return true; } return false; } // Adjust the rate based on the closest target. // If a faster rate is specified, then use the new rate so that we converge Loading @@ -88,7 +100,7 @@ final class RampAnimator<T> { mAnimating = true; mAnimatedValue = mCurrentValue; mLastFrameTimeNanos = System.nanoTime(); postCallback(); postAnimationCallback(); } return changed; Loading @@ -108,11 +120,15 @@ final class RampAnimator<T> { mListener = listener; } private void postCallback() { mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null); private void postAnimationCallback() { mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); } private void cancelAnimationCallback() { mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); } private final Runnable mCallback = new Runnable() { private final Runnable mAnimationCallback = new Runnable() { @Override // Choreographer callback public void run() { final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); Loading Loading @@ -144,7 +160,7 @@ final class RampAnimator<T> { } if (mTargetValue != mCurrentValue) { postCallback(); postAnimationCallback(); } else { mAnimating = false; if (mListener != null) { Loading Loading
services/core/java/com/android/server/display/DisplayPowerController.java +46 −11 Original line number Diff line number Diff line Loading @@ -227,6 +227,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // turning off the screen. private boolean mPendingScreenOff; // True if we have unfinished business and are holding a suspend blocker. private boolean mUnfinishedBusiness; // The elapsed real time when the screen on was blocked. private long mScreenOnBlockStartRealTime; Loading Loading @@ -633,22 +636,42 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedLowPower = true; } // Animate the screen brightness when the screen is on. if (state != Display.STATE_OFF) { animateScreenBrightness(brightness, slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } // Animate the screen state change unless already animating. animateScreenStateChange(state, performScreenOffTransition); // Report whether the display is ready for use and all changes have been applied. if (mustNotify && mPendingScreenOnUnblocker == null // Animate the screen brightness when the screen is on or dozing. // Skip the animation when the screen is off or suspended. final int actualState = mPowerState.getScreenState(); if (actualState == Display.STATE_ON || actualState == Display.STATE_DOZE) { animateScreenBrightness(brightness, slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } else { animateScreenBrightness(brightness, 0); } // Determine whether the display is ready for use in the newly requested state. // Note that we do not wait for the brightness ramp animation to complete before // reporting the display is ready because we only need to ensure the screen is in the // right power state even as it continues to converge on the desired brightness. final boolean ready = mPendingScreenOnUnblocker == null && !mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted() && !mScreenBrightnessRampAnimator.isAnimating() && mPowerState.waitUntilClean(mCleanListener)) { && mPowerState.waitUntilClean(mCleanListener); final boolean finished = ready && !mScreenBrightnessRampAnimator.isAnimating(); // Grab a wake lock if we have unfinished business. if (!finished && !mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Unfinished business..."); } mCallbacks.acquireSuspendBlocker(); mUnfinishedBusiness = true; } // Notify the power manager when ready. if (ready && mustNotify) { // Send state change. synchronized (mLock) { if (!mPendingRequestChangedLocked) { mDisplayReadyLocked = true; Loading @@ -660,6 +683,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } sendOnStateChangedWithWakelock(); } // Release the wake lock when we have no unfinished business. if (finished && mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Finished business..."); } mUnfinishedBusiness = false; mCallbacks.releaseSuspendBlocker(); } } @Override Loading Loading @@ -723,6 +755,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void animateScreenBrightness(int target, int rate) { if (DEBUG) { Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { try { mBatteryStats.noteScreenBrightness(target); Loading
services/core/java/com/android/server/display/DisplayPowerState.java +66 −62 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ final class DisplayPowerState { mBacklight = backlight; mColorFade = electronBeam; mPhotonicModulator = new PhotonicModulator(); mPhotonicModulator.start(); // 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, Loading Loading @@ -336,7 +337,7 @@ final class DisplayPowerState { /** * Updates the state of the screen and backlight asynchronously on a separate thread. */ private final class PhotonicModulator { private final class PhotonicModulator extends Thread { private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off private static final int INITIAL_BACKLIGHT = -1; // unknown Loading @@ -361,7 +362,7 @@ final class DisplayPowerState { if (!mChangeInProgress) { mChangeInProgress = true; AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); mLock.notifyAll(); } } return !mChangeInProgress; Loading @@ -369,6 +370,7 @@ final class DisplayPowerState { } public void dump(PrintWriter pw) { synchronized (mLock) { pw.println(); pw.println("Photonic Modulator State:"); pw.println(" mPendingState=" + Display.stateToString(mPendingState)); Loading @@ -377,12 +379,12 @@ final class DisplayPowerState { pw.println(" mActualBacklight=" + mActualBacklight); pw.println(" mChangeInProgress=" + mChangeInProgress); } } private final Runnable mTask = new Runnable() { @Override public void run() { // Apply pending changes until done. for (;;) { // Get pending change. final int state; final boolean stateChanged; final int backlight; Loading @@ -393,13 +395,19 @@ final class DisplayPowerState { backlight = mPendingBacklight; backlightChanged = (backlight != mActualBacklight); if (!stateChanged && !backlightChanged) { // All changed applied, notify outer class and wait for more. mChangeInProgress = false; break; postScreenUpdateThreadSafe(); try { mLock.wait(); } catch (InterruptedException ex) { } continue; } mActualState = state; mActualBacklight = backlight; } // Apply pending change. if (DEBUG) { Slog.d(TAG, "Updating screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); Loading @@ -415,9 +423,6 @@ final class DisplayPowerState { requestDisplayState(state); } } // Let the outer class know that all changes have been applied. postScreenUpdateThreadSafe(); } private void requestDisplayState(int state) { Loading @@ -438,6 +443,5 @@ final class DisplayPowerState { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }; } }
services/core/java/com/android/server/display/RampAnimator.java +29 −13 Original line number Diff line number Diff line Loading @@ -50,21 +50,33 @@ final class RampAnimator<T> { /** * Starts animating towards the specified value. * * If this is the first time the property is being set, the value jumps * directly to the target. * If this is the first time the property is being set or if the rate is 0, * the value jumps directly to the target. * * @param target The target value. * @param rate The convergence rate, in units per second. * @param rate The convergence rate in units per second, or 0 to set the value immediately. * @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) { if (mFirstTime || rate <= 0) { if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mProperty.setValue(mObject, target); mRate = 0; mTargetValue = target; mCurrentValue = target; mProperty.setValue(mObject, target); if (mAnimating) { mAnimating = false; cancelAnimationCallback(); } if (mListener != null) { mListener.onAnimationEnd(); } return true; } return false; } // Adjust the rate based on the closest target. // If a faster rate is specified, then use the new rate so that we converge Loading @@ -88,7 +100,7 @@ final class RampAnimator<T> { mAnimating = true; mAnimatedValue = mCurrentValue; mLastFrameTimeNanos = System.nanoTime(); postCallback(); postAnimationCallback(); } return changed; Loading @@ -108,11 +120,15 @@ final class RampAnimator<T> { mListener = listener; } private void postCallback() { mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null); private void postAnimationCallback() { mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); } private void cancelAnimationCallback() { mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); } private final Runnable mCallback = new Runnable() { private final Runnable mAnimationCallback = new Runnable() { @Override // Choreographer callback public void run() { final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); Loading Loading @@ -144,7 +160,7 @@ final class RampAnimator<T> { } if (mTargetValue != mCurrentValue) { postCallback(); postAnimationCallback(); } else { mAnimating = false; if (mListener != null) { Loading