blob: 4b6430d5197cc86b447ad1cb16ce5cbf113aecc2 [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;
Jeff Brown96307042012-07-27 15:51:34 -070025import android.util.Slog;
26import android.view.Choreographer;
Jeff Brown037c33e2014-04-09 00:31:55 -070027import android.view.Display;
Jeff Brown96307042012-07-27 15:51:34 -070028
Fiona Campbelld4eb2952019-11-04 17:19:56 +000029import com.android.internal.BrightnessSynchronizer;
30
Jeff Brown96307042012-07-27 15:51:34 -070031import java.io.PrintWriter;
32
33/**
Jeff Brown32dafe22012-10-19 17:04:30 -070034 * Controls the display power state.
35 * <p>
Jeff Brownad9ef192014-04-08 17:26:30 -070036 * This component is similar in nature to a {@link android.view.View} except that it
37 * describes the properties of a display. When properties are changed, the component
Jeff Brown32dafe22012-10-19 17:04:30 -070038 * invalidates itself and posts a callback to apply the changes in a consistent order.
39 * This mechanism enables multiple properties of the display power state to be animated
40 * together smoothly by the animation framework. Some of the work to blank or unblank
41 * the display is done on a separate thread to avoid blocking the looper.
42 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070043 * This component must only be created or accessed by the {@link Looper} thread
44 * that belongs to the {@link DisplayPowerController}.
Jeff Brown32dafe22012-10-19 17:04:30 -070045 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070046 * We don't need to worry about holding a suspend blocker here because the
Jeff Brownad9ef192014-04-08 17:26:30 -070047 * power manager does that for us whenever there is a change in progress.
Jeff Brown32dafe22012-10-19 17:04:30 -070048 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070049 */
50final class DisplayPowerState {
51 private static final String TAG = "DisplayPowerState";
52
53 private static boolean DEBUG = false;
Michael Wrightc3e6af82017-07-25 22:31:03 +010054 private static String COUNTER_COLOR_FADE = "ColorFadeLevel";
Jeff Brown96307042012-07-27 15:51:34 -070055
Jeff Brown32dafe22012-10-19 17:04:30 -070056 private final Handler mHandler;
Jeff Brown96307042012-07-27 15:51:34 -070057 private final Choreographer mChoreographer;
Jeff Brown037c33e2014-04-09 00:31:55 -070058 private final DisplayBlanker mBlanker;
Michael Lentine0839adb2014-07-29 18:47:56 -070059 private final ColorFade mColorFade;
Jeff Brown32dafe22012-10-19 17:04:30 -070060 private final PhotonicModulator mPhotonicModulator;
Jeff Brown96307042012-07-27 15:51:34 -070061
Jeff Brown037c33e2014-04-09 00:31:55 -070062 private int mScreenState;
Fiona Campbelld4eb2952019-11-04 17:19:56 +000063 private float mScreenBrightness;
Jeff Brown32dafe22012-10-19 17:04:30 -070064 private boolean mScreenReady;
65 private boolean mScreenUpdatePending;
66
Michael Lentine0839adb2014-07-29 18:47:56 -070067 private boolean mColorFadePrepared;
68 private float mColorFadeLevel;
69 private boolean mColorFadeReady;
70 private boolean mColorFadeDrawPending;
Jeff Brown96307042012-07-27 15:51:34 -070071
72 private Runnable mCleanListener;
73
Jeff Brown5d6443b2015-04-10 20:15:01 -070074 public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
Jeff Brown32dafe22012-10-19 17:04:30 -070075 mHandler = new Handler(true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -070076 mChoreographer = Choreographer.getInstance();
Jeff Brown037c33e2014-04-09 00:31:55 -070077 mBlanker = blanker;
Jeff Brown5d6443b2015-04-10 20:15:01 -070078 mColorFade = colorFade;
Jeff Brown32dafe22012-10-19 17:04:30 -070079 mPhotonicModulator = new PhotonicModulator();
Jeff Brown0a434772014-09-30 14:42:27 -070080 mPhotonicModulator.start();
Jeff Brown96307042012-07-27 15:51:34 -070081
Jeff Brownf75724b2012-08-25 13:34:32 -070082 // At boot time, we know that the screen is on and the electron beam
83 // animation is not playing. We don't know the screen's brightness though,
84 // so prepare to set it to a known state when the state is next applied.
85 // Although we set the brightness to full on here, the display power controller
86 // will reset the brightness to a new level immediately before the changes
87 // actually have a chance to be applied.
Jeff Brown037c33e2014-04-09 00:31:55 -070088 mScreenState = Display.STATE_ON;
Fiona Campbelld4eb2952019-11-04 17:19:56 +000089 mScreenBrightness = PowerManager.BRIGHTNESS_MAX;
Jeff Brown32dafe22012-10-19 17:04:30 -070090 scheduleScreenUpdate();
91
Michael Lentine0839adb2014-07-29 18:47:56 -070092 mColorFadePrepared = false;
93 mColorFadeLevel = 1.0f;
94 mColorFadeReady = true;
Jeff Brown96307042012-07-27 15:51:34 -070095 }
96
Michael Lentine0839adb2014-07-29 18:47:56 -070097 public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL =
Jeff Brown96307042012-07-27 15:51:34 -070098 new FloatProperty<DisplayPowerState>("electronBeamLevel") {
99 @Override
100 public void setValue(DisplayPowerState object, float value) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700101 object.setColorFadeLevel(value);
Jeff Brown96307042012-07-27 15:51:34 -0700102 }
103
104 @Override
105 public Float get(DisplayPowerState object) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700106 return object.getColorFadeLevel();
Jeff Brown96307042012-07-27 15:51:34 -0700107 }
108 };
109
Jeff Brown96307042012-07-27 15:51:34 -0700110
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000111 public static final FloatProperty<DisplayPowerState> SCREEN_BRIGHTNESS_FLOAT =
112 new FloatProperty<DisplayPowerState>("screenBrightnessFloat") {
113 @Override
114 public void setValue(DisplayPowerState object, float value) {
115 object.setScreenBrightness(value);
116 }
117
118 @Override
119 public Float get(DisplayPowerState object) {
120 return object.getScreenBrightness();
121 }
122 };
Jeff Brown96307042012-07-27 15:51:34 -0700123
124 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700125 * Sets whether the screen is on, off, or dozing.
Jeff Brown96307042012-07-27 15:51:34 -0700126 */
Jeff Brown037c33e2014-04-09 00:31:55 -0700127 public void setScreenState(int state) {
128 if (mScreenState != state) {
Jeff Brown96307042012-07-27 15:51:34 -0700129 if (DEBUG) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700130 Slog.d(TAG, "setScreenState: state=" + state);
Jeff Brown96307042012-07-27 15:51:34 -0700131 }
132
Jeff Brown037c33e2014-04-09 00:31:55 -0700133 mScreenState = state;
Jeff Brown32dafe22012-10-19 17:04:30 -0700134 mScreenReady = false;
135 scheduleScreenUpdate();
Jeff Brown96307042012-07-27 15:51:34 -0700136 }
137 }
138
139 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700140 * Gets the desired screen state.
Jeff Brown96307042012-07-27 15:51:34 -0700141 */
Jeff Brown037c33e2014-04-09 00:31:55 -0700142 public int getScreenState() {
143 return mScreenState;
Jeff Brown96307042012-07-27 15:51:34 -0700144 }
145
146 /**
Jeff Brown32dafe22012-10-19 17:04:30 -0700147 * Sets the display brightness.
148 *
Fiona Campbellc395a292020-04-24 11:55:30 +0100149 * @param brightness The brightness, ranges from 0.0f (minimum / off) to 1.0f (brightest).
Jeff Brown32dafe22012-10-19 17:04:30 -0700150 */
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000151 public void setScreenBrightness(float brightness) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700152 if (mScreenBrightness != brightness) {
153 if (DEBUG) {
154 Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
155 }
156
157 mScreenBrightness = brightness;
Jeff Brown037c33e2014-04-09 00:31:55 -0700158 if (mScreenState != Display.STATE_OFF) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700159 mScreenReady = false;
160 scheduleScreenUpdate();
161 }
162 }
163 }
164
165 /**
166 * Gets the screen brightness.
167 */
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000168 public float getScreenBrightness() {
Jeff Brown32dafe22012-10-19 17:04:30 -0700169 return mScreenBrightness;
170 }
171
172 /**
Jeff Brown96307042012-07-27 15:51:34 -0700173 * Prepares the electron beam to turn on or off.
174 * This method should be called before starting an animation because it
175 * can take a fair amount of time to prepare the electron beam surface.
176 *
Jeff Brown8b9cf1c2012-10-07 14:54:17 -0700177 * @param mode The electron beam animation mode to prepare.
Jeff Brown96307042012-07-27 15:51:34 -0700178 * @return True if the electron beam was prepared.
179 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700180 public boolean prepareColorFade(Context context, int mode) {
Narayan Kamath38819982017-07-06 18:15:30 +0100181 if (mColorFade == null || !mColorFade.prepare(context, mode)) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700182 mColorFadePrepared = false;
183 mColorFadeReady = true;
Jeff Brown32dafe22012-10-19 17:04:30 -0700184 return false;
185 }
186
Michael Lentine0839adb2014-07-29 18:47:56 -0700187 mColorFadePrepared = true;
188 mColorFadeReady = false;
189 scheduleColorFadeDraw();
Jeff Brown32dafe22012-10-19 17:04:30 -0700190 return true;
Jeff Brown96307042012-07-27 15:51:34 -0700191 }
192
193 /**
Michael Lentined73854d2015-09-25 10:55:26 -0700194 * Dismisses the color fade surface.
Jeff Brown96307042012-07-27 15:51:34 -0700195 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700196 public void dismissColorFade() {
Michael Wrightc3e6af82017-07-25 22:31:03 +0100197 Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100);
Narayan Kamath38819982017-07-06 18:15:30 +0100198 if (mColorFade != null) mColorFade.dismiss();
Michael Lentine0839adb2014-07-29 18:47:56 -0700199 mColorFadePrepared = false;
200 mColorFadeReady = true;
Jeff Brown96307042012-07-27 15:51:34 -0700201 }
202
Michael Lentined73854d2015-09-25 10:55:26 -0700203 /**
204 * Dismisses the color fade resources.
205 */
206 public void dismissColorFadeResources() {
Narayan Kamath38819982017-07-06 18:15:30 +0100207 if (mColorFade != null) mColorFade.dismissResources();
Michael Lentined73854d2015-09-25 10:55:26 -0700208 }
209
Jeff Brown96307042012-07-27 15:51:34 -0700210 /**
211 * Sets the level of the electron beam steering current.
212 *
213 * The display is blanked when the level is 0.0. In normal use, the electron
214 * beam should have a value of 1.0. The electron beam is unstable in between
215 * these states and the picture quality may be compromised. For best effect,
216 * the electron beam should be warmed up or cooled off slowly.
217 *
218 * Warning: Electron beam emits harmful radiation. Avoid direct exposure to
219 * skin or eyes.
220 *
221 * @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
222 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700223 public void setColorFadeLevel(float level) {
224 if (mColorFadeLevel != level) {
Jeff Brown96307042012-07-27 15:51:34 -0700225 if (DEBUG) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700226 Slog.d(TAG, "setColorFadeLevel: level=" + level);
Jeff Brown96307042012-07-27 15:51:34 -0700227 }
228
Michael Lentine0839adb2014-07-29 18:47:56 -0700229 mColorFadeLevel = level;
Jeff Brown037c33e2014-04-09 00:31:55 -0700230 if (mScreenState != Display.STATE_OFF) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700231 mScreenReady = false;
232 scheduleScreenUpdate(); // update backlight brightness
233 }
Michael Lentine0839adb2014-07-29 18:47:56 -0700234 if (mColorFadePrepared) {
235 mColorFadeReady = false;
236 scheduleColorFadeDraw();
Jeff Brown32dafe22012-10-19 17:04:30 -0700237 }
Jeff Brown96307042012-07-27 15:51:34 -0700238 }
239 }
240
241 /**
242 * Gets the level of the electron beam steering current.
243 */
Michael Lentine0839adb2014-07-29 18:47:56 -0700244 public float getColorFadeLevel() {
245 return mColorFadeLevel;
Jeff Brown96307042012-07-27 15:51:34 -0700246 }
247
248 /**
Jeff Brown96307042012-07-27 15:51:34 -0700249 * Returns true if no properties have been invalidated.
250 * Otherwise, returns false and promises to invoke the specified listener
251 * when the properties have all been applied.
252 * The listener always overrides any previously set listener.
253 */
254 public boolean waitUntilClean(Runnable listener) {
Michael Lentine0839adb2014-07-29 18:47:56 -0700255 if (!mScreenReady || !mColorFadeReady) {
Jeff Brown96307042012-07-27 15:51:34 -0700256 mCleanListener = listener;
257 return false;
258 } else {
259 mCleanListener = null;
260 return true;
261 }
262 }
263
264 public void dump(PrintWriter pw) {
265 pw.println();
266 pw.println("Display Power State:");
Jeff Brown037c33e2014-04-09 00:31:55 -0700267 pw.println(" mScreenState=" + Display.stateToString(mScreenState));
Jeff Brown96307042012-07-27 15:51:34 -0700268 pw.println(" mScreenBrightness=" + mScreenBrightness);
Jeff Brown32dafe22012-10-19 17:04:30 -0700269 pw.println(" mScreenReady=" + mScreenReady);
270 pw.println(" mScreenUpdatePending=" + mScreenUpdatePending);
Michael Lentine0839adb2014-07-29 18:47:56 -0700271 pw.println(" mColorFadePrepared=" + mColorFadePrepared);
272 pw.println(" mColorFadeLevel=" + mColorFadeLevel);
273 pw.println(" mColorFadeReady=" + mColorFadeReady);
274 pw.println(" mColorFadeDrawPending=" + mColorFadeDrawPending);
Jeff Brown96307042012-07-27 15:51:34 -0700275
Jeff Brown32dafe22012-10-19 17:04:30 -0700276 mPhotonicModulator.dump(pw);
Narayan Kamath38819982017-07-06 18:15:30 +0100277 if (mColorFade != null) mColorFade.dump(pw);
Jeff Brown96307042012-07-27 15:51:34 -0700278 }
279
Jeff Brown32dafe22012-10-19 17:04:30 -0700280 private void scheduleScreenUpdate() {
281 if (!mScreenUpdatePending) {
282 mScreenUpdatePending = true;
283 postScreenUpdateThreadSafe();
284 }
285 }
286
287 private void postScreenUpdateThreadSafe() {
288 mHandler.removeCallbacks(mScreenUpdateRunnable);
289 mHandler.post(mScreenUpdateRunnable);
290 }
291
Michael Lentine0839adb2014-07-29 18:47:56 -0700292 private void scheduleColorFadeDraw() {
293 if (!mColorFadeDrawPending) {
294 mColorFadeDrawPending = true;
Jeff Brown96307042012-07-27 15:51:34 -0700295 mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
Michael Lentine0839adb2014-07-29 18:47:56 -0700296 mColorFadeDrawRunnable, null);
Jeff Brown96307042012-07-27 15:51:34 -0700297 }
298 }
299
Jeff Brown32dafe22012-10-19 17:04:30 -0700300 private void invokeCleanListenerIfNeeded() {
301 final Runnable listener = mCleanListener;
Michael Lentine0839adb2014-07-29 18:47:56 -0700302 if (listener != null && mScreenReady && mColorFadeReady) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700303 mCleanListener = null;
304 listener.run();
305 }
306 }
307
308 private final Runnable mScreenUpdateRunnable = new Runnable() {
Jeff Brown96307042012-07-27 15:51:34 -0700309 @Override
310 public void run() {
Jeff Brown32dafe22012-10-19 17:04:30 -0700311 mScreenUpdatePending = false;
312
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000313 float brightnessState = mScreenState != Display.STATE_OFF
314 && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
315 if (mPhotonicModulator.setState(mScreenState, brightnessState)) {
Jeff Brown2d8a3902014-03-11 23:02:35 -0700316 if (DEBUG) {
317 Slog.d(TAG, "Screen ready");
318 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700319 mScreenReady = true;
320 invokeCleanListenerIfNeeded();
Jeff Brown2d8a3902014-03-11 23:02:35 -0700321 } else {
322 if (DEBUG) {
323 Slog.d(TAG, "Screen not ready");
324 }
Jeff Brown96307042012-07-27 15:51:34 -0700325 }
326 }
327 };
Jeff Brown32dafe22012-10-19 17:04:30 -0700328
Michael Lentine0839adb2014-07-29 18:47:56 -0700329 private final Runnable mColorFadeDrawRunnable = new Runnable() {
Jeff Brown32dafe22012-10-19 17:04:30 -0700330 @Override
331 public void run() {
Michael Lentine0839adb2014-07-29 18:47:56 -0700332 mColorFadeDrawPending = false;
Jeff Brown32dafe22012-10-19 17:04:30 -0700333
Michael Lentine0839adb2014-07-29 18:47:56 -0700334 if (mColorFadePrepared) {
335 mColorFade.draw(mColorFadeLevel);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100336 Trace.traceCounter(Trace.TRACE_TAG_POWER,
Michael Wright63a40062017-07-26 01:10:59 +0100337 COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100));
Jeff Brown32dafe22012-10-19 17:04:30 -0700338 }
339
Michael Lentine0839adb2014-07-29 18:47:56 -0700340 mColorFadeReady = true;
Jeff Brown32dafe22012-10-19 17:04:30 -0700341 invokeCleanListenerIfNeeded();
342 }
343 };
344
345 /**
346 * Updates the state of the screen and backlight asynchronously on a separate thread.
347 */
Jeff Brown0a434772014-09-30 14:42:27 -0700348 private final class PhotonicModulator extends Thread {
Jeff Brown037c33e2014-04-09 00:31:55 -0700349 private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000350 private static final float INITIAL_BACKLIGHT_FLOAT = PowerManager.BRIGHTNESS_INVALID_FLOAT;
Jeff Brown32dafe22012-10-19 17:04:30 -0700351
352 private final Object mLock = new Object();
353
Jeff Brown037c33e2014-04-09 00:31:55 -0700354 private int mPendingState = INITIAL_SCREEN_STATE;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000355 private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT;
Jeff Brown037c33e2014-04-09 00:31:55 -0700356 private int mActualState = INITIAL_SCREEN_STATE;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000357 private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT;
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700358 private boolean mStateChangeInProgress;
359 private boolean mBacklightChangeInProgress;
Jeff Brown32dafe22012-10-19 17:04:30 -0700360
Jeff Brownfaec22c82015-04-10 12:58:52 -0700361 public PhotonicModulator() {
362 super("PhotonicModulator");
363 }
364
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000365 public boolean setState(int state, float brightnessState) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700366 synchronized (mLock) {
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700367 boolean stateChanged = state != mPendingState;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000368 boolean backlightChanged = !BrightnessSynchronizer.floatEquals(
369 brightnessState, mPendingBacklight);
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700370 if (stateChanged || backlightChanged) {
Jeff Brown32dafe22012-10-19 17:04:30 -0700371 if (DEBUG) {
Jeff Brown037c33e2014-04-09 00:31:55 -0700372 Slog.d(TAG, "Requesting new screen state: state="
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000373 + Display.stateToString(state) + ", backlight=" + brightnessState);
Jeff Brown32dafe22012-10-19 17:04:30 -0700374 }
375
Jeff Brown037c33e2014-04-09 00:31:55 -0700376 mPendingState = state;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000377 mPendingBacklight = brightnessState;
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700378 boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
Michael Wright640666f2017-06-06 22:01:20 +0100379 mStateChangeInProgress = stateChanged || mStateChangeInProgress;
380 mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700381
382 if (!changeInProgress) {
Jeff Brown0a434772014-09-30 14:42:27 -0700383 mLock.notifyAll();
Jeff Brown32dafe22012-10-19 17:04:30 -0700384 }
385 }
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700386 return !mStateChangeInProgress;
Jeff Brown32dafe22012-10-19 17:04:30 -0700387 }
388 }
389
390 public void dump(PrintWriter pw) {
Jeff Brown0a434772014-09-30 14:42:27 -0700391 synchronized (mLock) {
392 pw.println();
393 pw.println("Photonic Modulator State:");
394 pw.println(" mPendingState=" + Display.stateToString(mPendingState));
395 pw.println(" mPendingBacklight=" + mPendingBacklight);
396 pw.println(" mActualState=" + Display.stateToString(mActualState));
397 pw.println(" mActualBacklight=" + mActualBacklight);
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700398 pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
399 pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
Jeff Brown0a434772014-09-30 14:42:27 -0700400 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700401 }
402
Jeff Brown0a434772014-09-30 14:42:27 -0700403 @Override
404 public void run() {
405 for (;;) {
406 // Get pending change.
407 final int state;
408 final boolean stateChanged;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000409 final float brightnessState;
Jeff Brown0a434772014-09-30 14:42:27 -0700410 final boolean backlightChanged;
411 synchronized (mLock) {
412 state = mPendingState;
413 stateChanged = (state != mActualState);
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000414 brightnessState = mPendingBacklight;
415 backlightChanged = !BrightnessSynchronizer.floatEquals(
416 brightnessState, mActualBacklight);
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700417 if (!stateChanged) {
418 // State changed applied, notify outer class.
Jeff Brown0a434772014-09-30 14:42:27 -0700419 postScreenUpdateThreadSafe();
Jorim Jaggi6e90ea02015-08-24 13:54:19 -0700420 mStateChangeInProgress = false;
421 }
422 if (!backlightChanged) {
423 mBacklightChangeInProgress = false;
424 }
425 if (!stateChanged && !backlightChanged) {
Jeff Brown0a434772014-09-30 14:42:27 -0700426 try {
427 mLock.wait();
428 } catch (InterruptedException ex) { }
429 continue;
Jeff Brown32dafe22012-10-19 17:04:30 -0700430 }
Jeff Brown0a434772014-09-30 14:42:27 -0700431 mActualState = state;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000432 mActualBacklight = brightnessState;
Jeff Brown32dafe22012-10-19 17:04:30 -0700433 }
434
Jeff Brown0a434772014-09-30 14:42:27 -0700435 // Apply pending change.
436 if (DEBUG) {
437 Slog.d(TAG, "Updating screen state: state="
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000438 + Display.stateToString(state) + ", backlight=" + brightnessState);
Jeff Brown0a434772014-09-30 14:42:27 -0700439 }
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000440 mBlanker.requestDisplayState(state, brightnessState);
Jeff Brown0a434772014-09-30 14:42:27 -0700441 }
442 }
Jeff Brown32dafe22012-10-19 17:04:30 -0700443 }
Jeff Brown96307042012-07-27 15:51:34 -0700444}