19630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/* 29630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Copyright (C) 2012 The Android Open Source Project 39630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 49630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 59630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * you may not use this file except in compliance with the License. 69630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * You may obtain a copy of the License at 79630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 89630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 99630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Unless required by applicable law or agreed to in writing, software 119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * See the License for the specific language governing permissions and 149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * limitations under the License. 159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 17ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brownpackage com.android.server.display; 189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 190839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentineimport android.content.Context; 2032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport android.os.Handler; 219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Looper; 229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.PowerManager; 23c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wrightimport android.os.Trace; 249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.FloatProperty; 259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.IntProperty; 269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.Slog; 279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.Choreographer; 28037c33eae74bee2774897d969d48947f9abe254fJeff Brownimport android.view.Display; 299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport java.io.PrintWriter; 319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/** 3332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Controls the display power state. 3432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * <p> 35ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * This component is similar in nature to a {@link android.view.View} except that it 36ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * describes the properties of a display. When properties are changed, the component 3732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * invalidates itself and posts a callback to apply the changes in a consistent order. 3832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * This mechanism enables multiple properties of the display power state to be animated 3932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * together smoothly by the animation framework. Some of the work to blank or unblank 4032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * the display is done on a separate thread to avoid blocking the looper. 4132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p><p> 429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This component must only be created or accessed by the {@link Looper} thread 439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * that belongs to the {@link DisplayPowerController}. 4432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p><p> 459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * We don't need to worry about holding a suspend blocker here because the 46ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * power manager does that for us whenever there is a change in progress. 4732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p> 489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownfinal class DisplayPowerState { 509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final String TAG = "DisplayPowerState"; 519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static boolean DEBUG = false; 53c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wright private static String COUNTER_COLOR_FADE = "ColorFadeLevel"; 549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Handler mHandler; 569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private final Choreographer mChoreographer; 57037c33eae74bee2774897d969d48947f9abe254fJeff Brown private final DisplayBlanker mBlanker; 580839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private final ColorFade mColorFade; 5932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final PhotonicModulator mPhotonicModulator; 609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 61037c33eae74bee2774897d969d48947f9abe254fJeff Brown private int mScreenState; 629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private int mScreenBrightness; 6332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mScreenReady; 6432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mScreenUpdatePending; 6532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 660839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private boolean mColorFadePrepared; 670839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private float mColorFadeLevel; 680839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private boolean mColorFadeReady; 690839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private boolean mColorFadeDrawPending; 709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private Runnable mCleanListener; 729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 735d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) { 7432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler = new Handler(true /*async*/); 759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mChoreographer = Choreographer.getInstance(); 76037c33eae74bee2774897d969d48947f9abe254fJeff Brown mBlanker = blanker; 775d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mColorFade = colorFade; 7832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPhotonicModulator = new PhotonicModulator(); 790a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown mPhotonicModulator.start(); 809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 81f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // At boot time, we know that the screen is on and the electron beam 82f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // animation is not playing. We don't know the screen's brightness though, 83f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // so prepare to set it to a known state when the state is next applied. 84f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // Although we set the brightness to full on here, the display power controller 85f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // will reset the brightness to a new level immediately before the changes 86f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // actually have a chance to be applied. 87037c33eae74bee2774897d969d48947f9abe254fJeff Brown mScreenState = Display.STATE_ON; 889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mScreenBrightness = PowerManager.BRIGHTNESS_ON; 8932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 9032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 910839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadePrepared = false; 920839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeLevel = 1.0f; 930839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = true; 949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 960839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL = 979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown new FloatProperty<DisplayPowerState>("electronBeamLevel") { 989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setValue(DisplayPowerState object, float value) { 1000839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine object.setColorFadeLevel(value); 1019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public Float get(DisplayPowerState object) { 1050839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine return object.getColorFadeLevel(); 1069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 1089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS = 1109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown new IntProperty<DisplayPowerState>("screenBrightness") { 1119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setValue(DisplayPowerState object, int value) { 1139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown object.setScreenBrightness(value); 1149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public Integer get(DisplayPowerState object) { 1189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return object.getScreenBrightness(); 1199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 1219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 123037c33eae74bee2774897d969d48947f9abe254fJeff Brown * Sets whether the screen is on, off, or dozing. 1249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 125037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void setScreenState(int state) { 126037c33eae74bee2774897d969d48947f9abe254fJeff Brown if (mScreenState != state) { 1279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 128037c33eae74bee2774897d969d48947f9abe254fJeff Brown Slog.d(TAG, "setScreenState: state=" + state); 1299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 131037c33eae74bee2774897d969d48947f9abe254fJeff Brown mScreenState = state; 13232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 13332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 1349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 138037c33eae74bee2774897d969d48947f9abe254fJeff Brown * Gets the desired screen state. 1399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 140037c33eae74bee2774897d969d48947f9abe254fJeff Brown public int getScreenState() { 141037c33eae74bee2774897d969d48947f9abe254fJeff Brown return mScreenState; 1429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 14532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Sets the display brightness. 14632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * 14732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest). 14832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 14932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void setScreenBrightness(int brightness) { 15032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mScreenBrightness != brightness) { 15132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (DEBUG) { 15232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); 15332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 15432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 15532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenBrightness = brightness; 156037c33eae74bee2774897d969d48947f9abe254fJeff Brown if (mScreenState != Display.STATE_OFF) { 15732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 15832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 15932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 16332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 16432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Gets the screen brightness. 16532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 16632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public int getScreenBrightness() { 16732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return mScreenBrightness; 16832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 17032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 1719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Prepares the electron beam to turn on or off. 1729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This method should be called before starting an animation because it 1739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * can take a fair amount of time to prepare the electron beam surface. 1749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 1758b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * @param mode The electron beam animation mode to prepare. 1769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @return True if the electron beam was prepared. 1779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1780839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine public boolean prepareColorFade(Context context, int mode) { 17938819989134819dc8a9b21ab8c696a0b24612e43Narayan Kamath if (mColorFade == null || !mColorFade.prepare(context, mode)) { 1800839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadePrepared = false; 1810839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = true; 18232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return false; 18332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 18432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 1850839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadePrepared = true; 1860839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = false; 1870839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine scheduleColorFadeDraw(); 18832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return true; 1899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 192d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine * Dismisses the color fade surface. 1939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1940839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine public void dismissColorFade() { 195c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wright Trace.traceCounter(Trace.TRACE_TAG_POWER, COUNTER_COLOR_FADE, 100); 19638819989134819dc8a9b21ab8c696a0b24612e43Narayan Kamath if (mColorFade != null) mColorFade.dismiss(); 1970839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadePrepared = false; 1980839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = true; 1999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 201d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine /** 202d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine * Dismisses the color fade resources. 203d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine */ 204d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine public void dismissColorFadeResources() { 20538819989134819dc8a9b21ab8c696a0b24612e43Narayan Kamath if (mColorFade != null) mColorFade.dismissResources(); 206d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine } 207d73854dbfde6e034ae0a6d12c52930c5284a08bbMichael Lentine 2089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Sets the level of the electron beam steering current. 2109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * The display is blanked when the level is 0.0. In normal use, the electron 2129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * beam should have a value of 1.0. The electron beam is unstable in between 2139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * these states and the picture quality may be compromised. For best effect, 2149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * the electron beam should be warmed up or cooled off slowly. 2159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Warning: Electron beam emits harmful radiation. Avoid direct exposure to 2179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * skin or eyes. 2189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @param level The level, ranges from 0.0 (full off) to 1.0 (full on). 2209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2210839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine public void setColorFadeLevel(float level) { 2220839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (mColorFadeLevel != level) { 2239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 2240839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine Slog.d(TAG, "setColorFadeLevel: level=" + level); 2259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2270839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeLevel = level; 228037c33eae74bee2774897d969d48947f9abe254fJeff Brown if (mScreenState != Display.STATE_OFF) { 22932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 23032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); // update backlight brightness 23132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2320839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (mColorFadePrepared) { 2330839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = false; 2340839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine scheduleColorFadeDraw(); 23532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Gets the level of the electron beam steering current. 2419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2420839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine public float getColorFadeLevel() { 2430839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine return mColorFadeLevel; 2449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Returns true if no properties have been invalidated. 2489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Otherwise, returns false and promises to invoke the specified listener 2499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * when the properties have all been applied. 2509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * The listener always overrides any previously set listener. 2519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public boolean waitUntilClean(Runnable listener) { 2530839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (!mScreenReady || !mColorFadeReady) { 2549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mCleanListener = listener; 2559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 2569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } else { 2579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mCleanListener = null; 2589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 2599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void dump(PrintWriter pw) { 2639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(); 2649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println("Display Power State:"); 265037c33eae74bee2774897d969d48947f9abe254fJeff Brown pw.println(" mScreenState=" + Display.stateToString(mScreenState)); 2669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mScreenBrightness=" + mScreenBrightness); 26732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mScreenReady=" + mScreenReady); 26832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mScreenUpdatePending=" + mScreenUpdatePending); 2690839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine pw.println(" mColorFadePrepared=" + mColorFadePrepared); 2700839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine pw.println(" mColorFadeLevel=" + mColorFadeLevel); 2710839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine pw.println(" mColorFadeReady=" + mColorFadeReady); 2720839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine pw.println(" mColorFadeDrawPending=" + mColorFadeDrawPending); 2739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 27432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPhotonicModulator.dump(pw); 27538819989134819dc8a9b21ab8c696a0b24612e43Narayan Kamath if (mColorFade != null) mColorFade.dump(pw); 2769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 27832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void scheduleScreenUpdate() { 27932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mScreenUpdatePending) { 28032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenUpdatePending = true; 28132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown postScreenUpdateThreadSafe(); 28232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 28332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 28432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 28532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void postScreenUpdateThreadSafe() { 28632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler.removeCallbacks(mScreenUpdateRunnable); 28732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler.post(mScreenUpdateRunnable); 28832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 28932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 2900839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private void scheduleColorFadeDraw() { 2910839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (!mColorFadeDrawPending) { 2920839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeDrawPending = true; 2939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, 2940839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeDrawRunnable, null); 2959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 29632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 29832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void invokeCleanListenerIfNeeded() { 29932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final Runnable listener = mCleanListener; 3000839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (listener != null && mScreenReady && mColorFadeReady) { 30132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mCleanListener = null; 30232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown listener.run(); 30332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 3049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 30632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Runnable mScreenUpdateRunnable = new Runnable() { 30732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown @Override 30832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void run() { 30932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenUpdatePending = false; 3109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 311037c33eae74bee2774897d969d48947f9abe254fJeff Brown int brightness = mScreenState != Display.STATE_OFF 3120839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine && mColorFadeLevel > 0f ? mScreenBrightness : 0; 313037c33eae74bee2774897d969d48947f9abe254fJeff Brown if (mPhotonicModulator.setState(mScreenState, brightness)) { 3142d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown if (DEBUG) { 3152d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown Slog.d(TAG, "Screen ready"); 3162d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown } 31732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = true; 31832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown invokeCleanListenerIfNeeded(); 3192d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown } else { 3202d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown if (DEBUG) { 3212d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown Slog.d(TAG, "Screen not ready"); 3222d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown } 3239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 32432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 32532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown }; 3269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3270839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine private final Runnable mColorFadeDrawRunnable = new Runnable() { 32832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown @Override 32932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void run() { 3300839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeDrawPending = false; 3319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3320839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine if (mColorFadePrepared) { 3330839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFade.draw(mColorFadeLevel); 334c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wright Trace.traceCounter(Trace.TRACE_TAG_POWER, 33563a40069d35f7cb5cf342d48ba176b06cb7d673bMichael Wright COUNTER_COLOR_FADE, Math.round(mColorFadeLevel * 100)); 336735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown } 337735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown 3380839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine mColorFadeReady = true; 33932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown invokeCleanListenerIfNeeded(); 34032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 34132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown }; 3429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 34332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 34432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Updates the state of the screen and backlight asynchronously on a separate thread. 34532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 3460a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown private final class PhotonicModulator extends Thread { 347037c33eae74bee2774897d969d48947f9abe254fJeff Brown private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off 34832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private static final int INITIAL_BACKLIGHT = -1; // unknown 34932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 35032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Object mLock = new Object(); 35132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 352037c33eae74bee2774897d969d48947f9abe254fJeff Brown private int mPendingState = INITIAL_SCREEN_STATE; 35332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private int mPendingBacklight = INITIAL_BACKLIGHT; 354037c33eae74bee2774897d969d48947f9abe254fJeff Brown private int mActualState = INITIAL_SCREEN_STATE; 35532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private int mActualBacklight = INITIAL_BACKLIGHT; 3566e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi private boolean mStateChangeInProgress; 3576e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi private boolean mBacklightChangeInProgress; 35832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 359faec22c8e19d123bdbcfe5ba2c1ec7fe21516faaJeff Brown public PhotonicModulator() { 360faec22c8e19d123bdbcfe5ba2c1ec7fe21516faaJeff Brown super("PhotonicModulator"); 361faec22c8e19d123bdbcfe5ba2c1ec7fe21516faaJeff Brown } 362faec22c8e19d123bdbcfe5ba2c1ec7fe21516faaJeff Brown 363037c33eae74bee2774897d969d48947f9abe254fJeff Brown public boolean setState(int state, int backlight) { 36432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown synchronized (mLock) { 3656e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi boolean stateChanged = state != mPendingState; 3666e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi boolean backlightChanged = backlight != mPendingBacklight; 3676e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi if (stateChanged || backlightChanged) { 36832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (DEBUG) { 369037c33eae74bee2774897d969d48947f9abe254fJeff Brown Slog.d(TAG, "Requesting new screen state: state=" 370037c33eae74bee2774897d969d48947f9abe254fJeff Brown + Display.stateToString(state) + ", backlight=" + backlight); 37132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 37232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 373037c33eae74bee2774897d969d48947f9abe254fJeff Brown mPendingState = state; 37432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPendingBacklight = backlight; 37532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 3766e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress; 377640666fcfd4f40ba69dbe459adea7b31407209acMichael Wright mStateChangeInProgress = stateChanged || mStateChangeInProgress; 378640666fcfd4f40ba69dbe459adea7b31407209acMichael Wright mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress; 3796e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi 3806e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi if (!changeInProgress) { 3810a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown mLock.notifyAll(); 38232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 38332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 3846e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi return !mStateChangeInProgress; 3859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 38832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void dump(PrintWriter pw) { 3890a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown synchronized (mLock) { 3900a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println(); 3910a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println("Photonic Modulator State:"); 3920a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println(" mPendingState=" + Display.stateToString(mPendingState)); 3930a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println(" mPendingBacklight=" + mPendingBacklight); 3940a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println(" mActualState=" + Display.stateToString(mActualState)); 3950a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown pw.println(" mActualBacklight=" + mActualBacklight); 3966e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi pw.println(" mStateChangeInProgress=" + mStateChangeInProgress); 3976e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress); 3980a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown } 3999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 40032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 4010a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown @Override 4020a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown public void run() { 4030a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown for (;;) { 4040a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown // Get pending change. 4050a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown final int state; 4060a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown final boolean stateChanged; 4070a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown final int backlight; 4080a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown final boolean backlightChanged; 4090a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown synchronized (mLock) { 4100a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown state = mPendingState; 4110a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown stateChanged = (state != mActualState); 4120a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown backlight = mPendingBacklight; 4130a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown backlightChanged = (backlight != mActualBacklight); 4146e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi if (!stateChanged) { 4156e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi // State changed applied, notify outer class. 4160a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown postScreenUpdateThreadSafe(); 4176e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi mStateChangeInProgress = false; 4186e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi } 4196e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi if (!backlightChanged) { 4206e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi mBacklightChangeInProgress = false; 4216e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi } 4226e90ea03365c6baddc13762c5a701b84540d8bf9Jorim Jaggi if (!stateChanged && !backlightChanged) { 4230a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown try { 4240a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown mLock.wait(); 4250a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown } catch (InterruptedException ex) { } 4260a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown continue; 42732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 4280a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown mActualState = state; 4290a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown mActualBacklight = backlight; 43032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 43132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 4320a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown // Apply pending change. 4330a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown if (DEBUG) { 4340a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown Slog.d(TAG, "Updating screen state: state=" 4350a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown + Display.stateToString(state) + ", backlight=" + backlight); 4360a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown } 4375d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mBlanker.requestDisplayState(state, backlight); 4383edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown } 4390a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown } 44032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 4419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown} 442