blob: 763f56ff918f7d7cd28141a59b6a7aca6ee1daa1 [file] [log] [blame]
Jeff Brown96307042012-07-27 15:51:34 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brownad9ef192014-04-08 17:26:30 -070017package com.android.server.display;
Jeff Brown96307042012-07-27 15:51:34 -070018
Michael Lentine0839adb2014-07-29 18:47:56 -070019import android.content.Context;
Jeff Brown32dafe22012-10-19 17:04:30 -070020import android.os.Handler;
Jeff Brown96307042012-07-27 15:51:34 -070021import android.os.Looper;
22import android.os.PowerManager;
Michael Wrightc3e6af82017-07-25 22:31:03 +010023import android.os.Trace;
Jeff Brown96307042012-07-27 15:51:34 -070024import android.util.FloatProperty;
25import android.util.IntProperty;
26import android.util.Slog;
27import android.view.Choreographer;
Jeff Brown037c33e2014-04-09 00:31:55 -070028import android.view.Display;
Jeff Brown96307042012-07-27 15:51:34 -070029
30import java.io.PrintWriter;
31
32/**
Jeff Brown32dafe22012-10-19 17:04:30 -070033 * Controls the display power state.
34 * <p>
Jeff Brownad9ef192014-04-08 17:26:30 -070035 * This component is similar in nature to a {@link android.view.View} except that it
36 * describes the properties of a display. When properties are changed, the component
Jeff Brown32dafe22012-10-19 17:04:30 -070037 * invalidates itself and posts a callback to apply the changes in a consistent order.
38 * This mechanism enables multiple properties of the display power state to be animated
39 * together smoothly by the animation framework. Some of the work to blank or unblank
40 * the display is done on a separate thread to avoid blocking the looper.
41 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070042 * This component must only be created or accessed by the {@link Looper} thread
43 * that belongs to the {@link DisplayPowerController}.
Jeff Brown32dafe22012-10-19 17:04:30 -070044 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070045 * We don't need to worry about holding a suspend blocker here because the
Jeff Brownad9ef192014-04-08 17:26:30 -070046 * power manager does that for us whenever there is a change in progress.
Jeff Brown32dafe22012-10-19 17:04:30 -070047 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070048 */
49final class DisplayPowerState {
50 private static final String TAG = "DisplayPowerState";
51
52 private static boolean DEBUG = false;
Michael Wrightc3e6af82017-07-25 22:31:03 +010053 private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
Jeff Brown96307042012-07-27 15:51:34 -070054
Jeff Brown32dafe22012-10-19 17:04:30 -070055 private final Handler mHandler;
Jeff Brown96307042012-07-27 15:51:34 -070056 private final Choreographer mChoreographer;
Jeff Brown037c33e2014-04-09 00:31:55 -070057 private final DisplayBlanker mBlanker;
Michael Lentine0839adb2014-07-29 18:47:56 -070058 private final ColorFade mColorFade;
Jeff Brown32dafe22012-10-19 17:04:30 -070059 private final PhotonicModulator mPhotonicModulator;
Jeff Brown96307042012-07-27 15:51:34 -070060
Jeff Brown037c33e2014-04-09 00:31:55 -070061 private int mScreenState;
Jeff Brown96307042012-07-27 15:51:34 -070062 private int mScreenBrightness;
Jeff Brown32dafe22012-10-19 17:04:30 -070063 private boolean mScreenReady;
64 private boolean mScreenUpdatePending;
65
Michael Lentine0839adb2014-07-29 18:47:56 -070066 private boolean mColorFadePrepared;
67 private float mColorFadeLevel;
68 private boolean mColorFadeReady;
69 private boolean mColorFadeDrawPending;
Jeff Brown96307042012-07-27 15:51:34 -070070
71 private Runnable mCleanListener;
72
Jeff Brown5d6443b2015-04-10 20:15:01 -070073 public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
Jeff Brown32dafe22012-10-19 17:04:30 -070074 mHandler = new Handler(true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -070075 mChoreographer = Choreographer.getInstance();
Jeff Brown037c33e2014-04-09 00:31:55 -070076 mBlanker = blanker;
Jeff Brown5d6443b2015-04-10 20:15:01 -070077 mColorFade = colorFade;
Jeff Brown32dafe22012-10-19 17:04:30 -070078 mPhotonicModulator = new PhotonicModulator();
Jeff Brown0a434772014-09-30 14:42:27 -070079 mPhotonicModulator.start();
Jeff Brown96307042012-07-27 15:51:34 -070080
Jeff Brownf75724b2012-08-25 13:34:32 -070081 // At boot time, we know that the screen is on and the electron beam
82 // animation is not playing. We don't know the screen's brightness though,
83 // so prepare to set it to a known state when the state is next applied.
84 // Although we set the brightness to full on here, the display power controller
85 // will reset the brightness to a new level immediately before the changes
86 // actually have a chance to be applied.
Jeff Brown037c33e2014-04-09 00:31:55 -070087 mScreenState = Display.STATE_ON;
Jeff Brown96307042012-07-27 15:51:34 -070088 mScreenBrightness = PowerManager.BRIGHTNESS_ON;
Jeff Brown32dafe22012-10-19 17:04:30 -070089 scheduleScreenUpdate();
90
Michael Lentine0839adb2014-07-29 18:47:56 -070091 mColorFadePrepared = false;
92 mColorFadeLevel = 1.0f;
93 mColorFadeReady = true;
Jeff Brown96307042012-07-27 15:51:34 -070094 }
95
Michael Lentine0839adb2014-07-29 18:47:56 -070096 public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL =
Jeff Brown96307042012-07-27 15:51:34 -070097 new FloatProperty<DisplayPowerState>("electronBeamLevel") {
98 @Override
99 public void setValue(DisplayPowerState object, float value) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700100 object.setColorFadeLevel(value);
Jeff Brown96307042012-07-27 15:51:34 -0700101 }
102
103 @Override
104 public Float get(DisplayPowerState object) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700105 return object.getColorFadeLevel();
Jeff Brown96307042012-07-27 15:51:34 -0700106 }
107 };
108
109 public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
110 new IntProperty<DisplayPowerState>("screenBrightness") {
111 @Override
112 public void setValue(DisplayPowerState object, int value) {
113 object.setScreenBrightness(value);
114 }
115
116 @Override
117 public Integer get(DisplayPowerState object) {
118 return object.getScreenBrightness();
119 }
120 };
121
122 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700123 * Sets whether the screen is on, off, or dozing.
Jeff Brown96307042012-07-27 15:51:34 -0700124 */
Jeff Brown037c33e2014-04-09 00:31:55 -0700125 public void setScreenState(int state) {
126 if (mScreenState != state) {
Jeff Brown96307042012-07-27 15:51:34 -0700127 if (DEBUG) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700128 Slog.d(TAG, "setScreenState: state=" + state);
Jeff Brown96307042012-07-27 15:51:34 -0700129 }
130
Jeff Brown037c33e2014-04-09 00:31:55 -0700131 mScreenState = state;
Jeff Brown32dafe22012-10-19 17:04:30 -0700132 mScreenReady = false;
133 scheduleScreenUpdate();
Jeff Brown96307042012-07-27 15:51:34 -0700134 }
135 }
136
137 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700138 * Gets the desired screen state.
Jeff Brown96307042012-07-27 15:51:34 -0700139 */
Jeff Brown037c33e2014-04-09 00:31:55 -0700140 public int getScreenState() {
141 return mScreenState;
Jeff Brown96307042012-07-27 15:51:34 -0700142 }
143
144 /**
Jeff Brown32dafe22012-10-19 17:04:30 -0700145 * Sets the display brightness.
146 *
147 * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest).
148 */
149 public void setScreenBrightness(int brightness) {
150 if (mScreenBrightness != brightness) {
151 if (DEBUG) {
152 Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
153 }
154
155 mScreenBrightness = brightness;
Jeff Brown037c33e2014-04-09 00:31:55 -0700156 if (mScreenState != Display.STATE_OFF) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700157 mScreenReady = false;
158 scheduleScreenUpdate();
159 }
160 }
161 }
162
163 /**
164 * Gets the screen brightness.
165 */
166 public int getScreenBrightness() {
167 return mScreenBrightness;
168 }
169
170 /**
Jeff Brown96307042012-07-27 15:51:34 -0700171 * Prepares the electron beam to turn on or off.
172 * This method should be called before starting an animation because it
173 * can take a fair amount of time to prepare the electron beam surface.
174 *
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700175 * @param mode The electron beam animation mode to prepare.
Jeff Brown96307042012-07-27 15:51:34 -0700176 * @return True if the electron beam was prepared.
177 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700178 public boolean prepareColorFade(Context context, int mode) {
Narayan Kamath38819982017-07-06 18:15:30 +0100179 if (mColorFade == null || !mColorFade.prepare(context, mode)) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700180 mColorFadePrepared = false;
181 mColorFadeReady = true;
Jeff Brown32dafe22012-10-19 17:04:30 -0700182 return false;
183 }
184
Michael Lentine0839adb2014-07-29 18:47:56 -0700185 mColorFadePrepared = true;
186 mColorFadeReady = false;
187 scheduleColorFadeDraw();
Jeff Brown32dafe22012-10-19 17:04:30 -0700188 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700189 }
190
191 /**
Michael Lentined73854d2015-09-25 10:55:26 -0700192 * Dismisses the color fade surface.
Jeff Brown96307042012-07-27 15:51:34 -0700193 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700194 public void dismissColorFade() {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100195 Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
Narayan Kamath38819982017-07-06 18:15:30 +0100196 if (mColorFade != null) mColorFade.dismiss();
Michael Lentine0839adb2014-07-29 18:47:56 -0700197 mColorFadePrepared = false;
198 mColorFadeReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700199 }
200
Michael Lentined73854d2015-09-25 10:55:26 -0700201 /**
202 * Dismisses the color fade resources.
203 */
204 public void dismissColorFadeResources() {
Narayan Kamath38819982017-07-06 18:15:30 +0100205 if (mColorFade != null) mColorFade.dismissResources();
Michael Lentined73854d2015-09-25 10:55:26 -0700206 }
207
Jeff Brown96307042012-07-27 15:51:34 -0700208 /**
209 * Sets the level of the electron beam steering current.
210 *
211 * The display is blanked when the level is 0.0. In normal use, the electron
212 * beam should have a value of 1.0. The electron beam is unstable in between
213 * these states and the picture quality may be compromised. For best effect,
214 * the electron beam should be warmed up or cooled off slowly.
215 *
216 * Warning: Electron beam emits harmful radiation. Avoid direct exposure to
217 * skin or eyes.
218 *
219 * @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
220 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700221 public void setColorFadeLevel(float level) {
222 if (mColorFadeLevel != level) {
Jeff Brown96307042012-07-27 15:51:34 -0700223 if (DEBUG) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700224 Slog.d(TAG, "setColorFadeLevel: level=" + level);
Jeff Brown96307042012-07-27 15:51:34 -0700225 }
226
Michael Lentine0839adb2014-07-29 18:47:56 -0700227 mColorFadeLevel = level;
Jeff Brown037c33e2014-04-09 00:31:55 -0700228 if (mScreenState != Display.STATE_OFF) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700229 mScreenReady = false;
230 scheduleScreenUpdate(); // update backlight brightness
231 }
Michael Lentine0839adb2014-07-29 18:47:56 -0700232 if (mColorFadePrepared) {
233 mColorFadeReady = false;
234 scheduleColorFadeDraw();
Jeff Brown32dafe22012-10-19 17:04:30 -0700235 }
Jeff Brown96307042012-07-27 15:51:34 -0700236 }
237 }
238
239 /**
240 * Gets the level of the electron beam steering current.
241 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700242 public float getColorFadeLevel() {
243 return mColorFadeLevel;
Jeff Brown96307042012-07-27 15:51:34 -0700244 }
245
246 /**
Jeff Brown96307042012-07-27 15:51:34 -0700247 * Returns true if no properties have been invalidated.
248 * Otherwise, returns false and promises to invoke the specified listener
249 * when the properties have all been applied.
250 * The listener always overrides any previously set listener.
251 */
252 public boolean waitUntilClean(Runnable listener) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700253 if (!mScreenReady || !mColorFadeReady) {
Jeff Brown96307042012-07-27 15:51:34 -0700254 mCleanListener = listener;
255 return false;
256 } else {
257 mCleanListener = null;
258 return true;
259 }
260 }
261
262 public void dump(PrintWriter pw) {
263 pw.println();
264 pw.println("Display Power State:");
Jeff Brown037c33e2014-04-09 00:31:55 -0700265 pw.println(" mScreenState=" + Display.stateToString(mScreenState));
Jeff Brown96307042012-07-27 15:51:34 -0700266 pw.println(" mScreenBrightness=" + mScreenBrightness);
Jeff Brown32dafe22012-10-19 17:04:30 -0700267 pw.println(" mScreenReady=" + mScreenReady);
268 pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
Michael Lentine0839adb2014-07-29 18:47:56 -0700269 pw.println(" mColorFadePrepared=" + mColorFadePrepared);
270 pw.println(" mColorFadeLevel=" + mColorFadeLevel);
271 pw.println(" mColorFadeReady=" + mColorFadeReady);
272 pw.println(" mColorFadeDrawPending=" + mColorFadeDrawPending);
Jeff Brown96307042012-07-27 15:51:34 -0700273
Jeff Brown32dafe22012-10-19 17:04:30 -0700274 mPhotonicModulator.dump(pw);
Narayan Kamath38819982017-07-06 18:15:30 +0100275 if (mColorFade != null) mColorFade.dump(pw);
Jeff Brown96307042012-07-27 15:51:34 -0700276 }
277
Jeff Brown32dafe22012-10-19 17:04:30 -0700278 private void scheduleScreenUpdate() {
279 if (!mScreenUpdatePending) {
280 mScreenUpdatePending = true;
281 postScreenUpdateThreadSafe();
282 }
283 }
284
285 private void postScreenUpdateThreadSafe() {
286 mHandler.removeCallbacks(mScreenUpdateRunnable);
287 mHandler.post(mScreenUpdateRunnable);
288 }
289
Michael Lentine0839adb2014-07-29 18:47:56 -0700290 private void scheduleColorFadeDraw() {
291 if (!mColorFadeDrawPending) {
292 mColorFadeDrawPending = true;
Jeff Brown96307042012-07-27 15:51:34 -0700293 mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
Michael Lentine0839adb2014-07-29 18:47:56 -0700294 mColorFadeDrawRunnable, null);
Jeff Brown96307042012-07-27 15:51:34 -0700295 }
296 }
297
Jeff Brown32dafe22012-10-19 17:04:30 -0700298 private void invokeCleanListenerIfNeeded() {
299 final Runnable listener = mCleanListener;
Michael Lentine0839adb2014-07-29 18:47:56 -0700300 if (listener != null && mScreenReady && mColorFadeReady) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700301 mCleanListener = null;
302 listener.run();
303 }
304 }
305
306 private final Runnable mScreenUpdateRunnable = new Runnable() {
Jeff Brown96307042012-07-27 15:51:34 -0700307 @Override
308 public void run() {
Jeff Brown32dafe22012-10-19 17:04:30 -0700309 mScreenUpdatePending = false;
310
Jeff Brown037c33e2014-04-09 00:31:55 -0700311 int brightness = mScreenState != Display.STATE_OFF
Michael Lentine0839adb2014-07-29 18:47:56 -0700312 && mColorFadeLevel > 0f ? mScreenBrightness : 0;
Jeff Brown037c33e2014-04-09 00:31:55 -0700313 if (mPhotonicModulator.setState(mScreenState, brightness)) {
Jeff Brown2d8a3902014-03-11 23:02:35 -0700314 if (DEBUG) {
315 Slog.d(TAG, "Screen ready");
316 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700317 mScreenReady = true;
318 invokeCleanListenerIfNeeded();
Jeff Brown2d8a3902014-03-11 23:02:35 -0700319 } else {
320 if (DEBUG) {
321 Slog.d(TAG, "Screen not ready");
322 }
Jeff Brown96307042012-07-27 15:51:34 -0700323 }
324 }
325 };
Jeff Brown32dafe22012-10-19 17:04:30 -0700326
Michael Lentine0839adb2014-07-29 18:47:56 -0700327 private final Runnable mColorFadeDrawRunnable = new Runnable() {
Jeff Brown32dafe22012-10-19 17:04:30 -0700328 @Override
329 public void run() {
Michael Lentine0839adb2014-07-29 18:47:56 -0700330 mColorFadeDrawPending = false;
Jeff Brown32dafe22012-10-19 17:04:30 -0700331
Michael Lentine0839adb2014-07-29 18:47:56 -0700332 if (mColorFadePrepared) {
333 mColorFade.draw(mColorFadeLevel);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100334 Trace.traceCounter(Trace.TRACE_TAG_POWER,
Michael Wright63a40062017-07-26 01:10:59 +0100335 COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100));
Jeff Brown32dafe22012-10-19 17:04:30 -0700336 }
337
Michael Lentine0839adb2014-07-29 18:47:56 -0700338 mColorFadeReady = true;
Jeff Brown32dafe22012-10-19 17:04:30 -0700339 invokeCleanListenerIfNeeded();
340 }
341 };
342
343 /**
344 * Updates the state of the screen and backlight asynchronously on a separate thread.
345 */
Jeff Brown0a434772014-09-30 14:42:27 -0700346 private final class PhotonicModulator extends Thread {
Jeff Brown037c33e2014-04-09 00:31:55 -0700347 private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
Jeff Brown32dafe22012-10-19 17:04:30 -0700348 private static final int INITIAL_BACKLIGHT = -1; // unknown
349
350 private final Object mLock = new Object();
351
Jeff Brown037c33e2014-04-09 00:31:55 -0700352 private int mPendingState = INITIAL_SCREEN_STATE;
Jeff Brown32dafe22012-10-19 17:04:30 -0700353 private int mPendingBacklight = INITIAL_BACKLIGHT;
Jeff Brown037c33e2014-04-09 00:31:55 -0700354 private int mActualState = INITIAL_SCREEN_STATE;
Jeff Brown32dafe22012-10-19 17:04:30 -0700355 private int mActualBacklight = INITIAL_BACKLIGHT;
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700356 private boolean mStateChangeInProgress;
357 private boolean mBacklightChangeInProgress;
Jeff Brown32dafe22012-10-19 17:04:30 -0700358
Jeff Brownfaec22c82015-04-10 12:58:52 -0700359 public PhotonicModulator() {
360 super("PhotonicModulator");
361 }
362
Jeff Brown037c33e2014-04-09 00:31:55 -0700363 public boolean setState(int state, int backlight) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700364 synchronized (mLock) {
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700365 boolean stateChanged = state != mPendingState;
366 boolean backlightChanged = backlight != mPendingBacklight;
367 if (stateChanged || backlightChanged) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700368 if (DEBUG) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700369 Slog.d(TAG, "Requesting new screen state: state="
370 + Display.stateToString(state) + ", backlight=" + backlight);
Jeff Brown32dafe22012-10-19 17:04:30 -0700371 }
372
Jeff Brown037c33e2014-04-09 00:31:55 -0700373 mPendingState = state;
Jeff Brown32dafe22012-10-19 17:04:30 -0700374 mPendingBacklight = backlight;
375
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700376 boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
Michael Wright640666f2017-06-06 22:01:20 +0100377 mStateChangeInProgress = stateChanged || mStateChangeInProgress;
378 mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700379
380 if (!changeInProgress) {
Jeff Brown0a434772014-09-30 14:42:27 -0700381 mLock.notifyAll();
Jeff Brown32dafe22012-10-19 17:04:30 -0700382 }
383 }
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700384 return !mStateChangeInProgress;
Jeff Brown32dafe22012-10-19 17:04:30 -0700385 }
386 }
387
388 public void dump(PrintWriter pw) {
Jeff Brown0a434772014-09-30 14:42:27 -0700389 synchronized (mLock) {
390 pw.println();
391 pw.println("Photonic Modulator State:");
392 pw.println(" mPendingState=" + Display.stateToString(mPendingState));
393 pw.println(" mPendingBacklight=" + mPendingBacklight);
394 pw.println(" mActualState=" + Display.stateToString(mActualState));
395 pw.println(" mActualBacklight=" + mActualBacklight);
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700396 pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
397 pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
Jeff Brown0a434772014-09-30 14:42:27 -0700398 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700399 }
400
Jeff Brown0a434772014-09-30 14:42:27 -0700401 @Override
402 public void run() {
403 for (;;) {
404 // Get pending change.
405 final int state;
406 final boolean stateChanged;
407 final int backlight;
408 final boolean backlightChanged;
409 synchronized (mLock) {
410 state = mPendingState;
411 stateChanged = (state != mActualState);
412 backlight = mPendingBacklight;
413 backlightChanged = (backlight != mActualBacklight);
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700414 if (!stateChanged) {
415 // State changed applied, notify outer class.
Jeff Brown0a434772014-09-30 14:42:27 -0700416 postScreenUpdateThreadSafe();
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700417 mStateChangeInProgress = false;
418 }
419 if (!backlightChanged) {
420 mBacklightChangeInProgress = false;
421 }
422 if (!stateChanged && !backlightChanged) {
Jeff Brown0a434772014-09-30 14:42:27 -0700423 try {
424 mLock.wait();
425 } catch (InterruptedException ex) { }
426 continue;
Jeff Brown32dafe22012-10-19 17:04:30 -0700427 }
Jeff Brown0a434772014-09-30 14:42:27 -0700428 mActualState = state;
429 mActualBacklight = backlight;
Jeff Brown32dafe22012-10-19 17:04:30 -0700430 }
431
Jeff Brown0a434772014-09-30 14:42:27 -0700432 // Apply pending change.
433 if (DEBUG) {
434 Slog.d(TAG, "Updating screen state: state="
435 + Display.stateToString(state) + ", backlight=" + backlight);
436 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700437 mBlanker.requestDisplayState(state, backlight);
Jeff Brown0a434772014-09-30 14:42:27 -0700438 }
439 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700440 }
Jeff Brown96307042012-07-27 15:51:34 -0700441}