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 179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownpackage com.android.server.power; 189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport com.android.server.LightsService; 2032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 2132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport android.os.AsyncTask; 2232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport android.os.Handler; 239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Looper; 249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.PowerManager; 259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.FloatProperty; 269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.IntProperty; 279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.Slog; 289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.Choreographer; 299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport java.io.PrintWriter; 319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/** 3332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Controls the display power state. 3432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * <p> 359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This component is similar in nature to a {@link View} except that it describes 369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 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 4632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * {@link PowerManagerService} does that for us whenever there is a change 4732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * in progress. 4832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p> 499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownfinal class DisplayPowerState { 519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final String TAG = "DisplayPowerState"; 529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static boolean DEBUG = false; 549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Handler mHandler; 569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private final Choreographer mChoreographer; 578b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private final ElectronBeam mElectronBeam; 589e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown private final DisplayBlanker mDisplayBlanker; 5932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final LightsService.Light mBacklight; 6032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final PhotonicModulator mPhotonicModulator; 619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean mScreenOn; 639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private int mScreenBrightness; 6432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mScreenReady; 6532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mScreenUpdatePending; 6632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 6732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mElectronBeamPrepared; 6832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private float mElectronBeamLevel; 6932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mElectronBeamReady; 7032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mElectronBeamDrawPending; 719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private Runnable mCleanListener; 739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public DisplayPowerState(ElectronBeam electronBean, 7532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown DisplayBlanker displayBlanker, LightsService.Light backlight) { 7632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler = new Handler(true /*async*/); 779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mChoreographer = Choreographer.getInstance(); 789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mElectronBeam = electronBean; 799e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown mDisplayBlanker = displayBlanker; 8032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mBacklight = backlight; 8132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPhotonicModulator = new PhotonicModulator(); 829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 83f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // At boot time, we know that the screen is on and the electron beam 84f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // animation is not playing. We don't know the screen's brightness though, 85f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // so prepare to set it to a known state when the state is next applied. 86f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // Although we set the brightness to full on here, the display power controller 87f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // will reset the brightness to a new level immediately before the changes 88f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown // actually have a chance to be applied. 899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mScreenOn = true; 909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mScreenBrightness = PowerManager.BRIGHTNESS_ON; 9132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 9232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 9332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamPrepared = false; 9432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamLevel = 1.0f; 9532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = true; 969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public static final FloatProperty<DisplayPowerState> ELECTRON_BEAM_LEVEL = 999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown new FloatProperty<DisplayPowerState>("electronBeamLevel") { 1009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setValue(DisplayPowerState object, float value) { 1029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown object.setElectronBeamLevel(value); 1039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public Float get(DisplayPowerState object) { 1079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return object.getElectronBeamLevel(); 1089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 1109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS = 1129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown new IntProperty<DisplayPowerState>("screenBrightness") { 1139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setValue(DisplayPowerState object, int value) { 1159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown object.setScreenBrightness(value); 1169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown @Override 1199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public Integer get(DisplayPowerState object) { 1209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return object.getScreenBrightness(); 1219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 1239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 1259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Sets whether the screen is on or off. 1269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setScreenOn(boolean on) { 1289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mScreenOn != on) { 1299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 1309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "setScreenOn: on=" + on); 1319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mScreenOn = on; 13432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 13532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 1369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 1409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Returns true if the screen is on. 1419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public boolean isScreenOn() { 1439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return mScreenOn; 1449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 14732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Sets the display brightness. 14832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * 14932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest). 15032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 15132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void setScreenBrightness(int brightness) { 15232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mScreenBrightness != brightness) { 15332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (DEBUG) { 15432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); 15532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 15632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 15732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenBrightness = brightness; 15832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mScreenOn) { 15932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 16032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); 16132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 16432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 16532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 16632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Gets the screen brightness. 16732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 16832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public int getScreenBrightness() { 16932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return mScreenBrightness; 17032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 17132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 17232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 1739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Prepares the electron beam to turn on or off. 1749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This method should be called before starting an animation because it 1759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * can take a fair amount of time to prepare the electron beam surface. 1769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 1778b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * @param mode The electron beam animation mode to prepare. 1789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @return True if the electron beam was prepared. 1799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1808b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown public boolean prepareElectronBeam(int mode) { 18132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mElectronBeam.prepare(mode)) { 18232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamPrepared = false; 18332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = true; 18432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return false; 18532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 18632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 18732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamPrepared = true; 18832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = false; 18932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleElectronBeamDraw(); 19032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return true; 1919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 1949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Dismisses the electron beam surface. 1959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void dismissElectronBeam() { 1978b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown mElectronBeam.dismiss(); 19832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamPrepared = false; 19932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = true; 2009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Sets the level of the electron beam steering current. 2049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * The display is blanked when the level is 0.0. In normal use, the electron 2069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * beam should have a value of 1.0. The electron beam is unstable in between 2079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * these states and the picture quality may be compromised. For best effect, 2089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * the electron beam should be warmed up or cooled off slowly. 2099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Warning: Electron beam emits harmful radiation. Avoid direct exposure to 2119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * skin or eyes. 2129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @param level The level, ranges from 0.0 (full off) to 1.0 (full on). 2149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void setElectronBeamLevel(float level) { 2169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mElectronBeamLevel != level) { 2179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 2189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "setElectronBeamLevel: level=" + level); 2199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mElectronBeamLevel = level; 22232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mScreenOn) { 22332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = false; 22432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleScreenUpdate(); // update backlight brightness 22532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 22632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mElectronBeamPrepared) { 22732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = false; 22832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown scheduleElectronBeamDraw(); 22932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Gets the level of the electron beam steering current. 2359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public float getElectronBeamLevel() { 2379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return mElectronBeamLevel; 2389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Returns true if no properties have been invalidated. 2429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Otherwise, returns false and promises to invoke the specified listener 2439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * when the properties have all been applied. 2449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * The listener always overrides any previously set listener. 2459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public boolean waitUntilClean(Runnable listener) { 24732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mScreenReady || !mElectronBeamReady) { 2489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mCleanListener = listener; 2499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 2509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } else { 2519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mCleanListener = null; 2529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 2539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void dump(PrintWriter pw) { 2579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(); 2589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println("Display Power State:"); 2599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mScreenOn=" + mScreenOn); 2609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mScreenBrightness=" + mScreenBrightness); 26132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mScreenReady=" + mScreenReady); 26232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mScreenUpdatePending=" + mScreenUpdatePending); 26332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mElectronBeamPrepared=" + mElectronBeamPrepared); 2649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mElectronBeamLevel=" + mElectronBeamLevel); 26532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mElectronBeamReady=" + mElectronBeamReady); 26632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mElectronBeamDrawPending=" + mElectronBeamDrawPending); 2679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 26832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPhotonicModulator.dump(pw); 2698b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown mElectronBeam.dump(pw); 2709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 27232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void scheduleScreenUpdate() { 27332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mScreenUpdatePending) { 27432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenUpdatePending = true; 27532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown postScreenUpdateThreadSafe(); 27632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 27732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 27832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 27932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void postScreenUpdateThreadSafe() { 28032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler.removeCallbacks(mScreenUpdateRunnable); 28132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mHandler.post(mScreenUpdateRunnable); 28232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 28332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 28432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void scheduleElectronBeamDraw() { 28532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mElectronBeamDrawPending) { 28632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamDrawPending = true; 2879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, 28832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamDrawRunnable, null); 2899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 29032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 29232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private void invokeCleanListenerIfNeeded() { 29332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final Runnable listener = mCleanListener; 29432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (listener != null && mScreenReady && mElectronBeamReady) { 29532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mCleanListener = null; 29632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown listener.run(); 29732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 2989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 30032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Runnable mScreenUpdateRunnable = new Runnable() { 30132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown @Override 30232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void run() { 30332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenUpdatePending = false; 3049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 305356bd4cf2c6db38c61c79e81fd5d9d119d299b8dJeff Brown int brightness = mScreenOn && mElectronBeamLevel > 0f ? mScreenBrightness : 0; 306356bd4cf2c6db38c61c79e81fd5d9d119d299b8dJeff Brown if (mPhotonicModulator.setState(mScreenOn, brightness)) { 30732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mScreenReady = true; 30832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown invokeCleanListenerIfNeeded(); 3099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 31032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 31132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown }; 3129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 31332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Runnable mElectronBeamDrawRunnable = new Runnable() { 31432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown @Override 31532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void run() { 31632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamDrawPending = false; 3179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 31832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (mElectronBeamPrepared) { 31932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeam.draw(mElectronBeamLevel); 320735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown } 321735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown 32232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mElectronBeamReady = true; 32332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown invokeCleanListenerIfNeeded(); 32432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 32532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown }; 3269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 32732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown /** 32832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Updates the state of the screen and backlight asynchronously on a separate thread. 32932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown */ 33032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final class PhotonicModulator { 33132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private static final boolean INITIAL_SCREEN_ON = false; // unknown, assume off 33232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private static final int INITIAL_BACKLIGHT = -1; // unknown 33332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 33432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Object mLock = new Object(); 33532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 33632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mPendingOn = INITIAL_SCREEN_ON; 33732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private int mPendingBacklight = INITIAL_BACKLIGHT; 33832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mActualOn = INITIAL_SCREEN_ON; 33932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private int mActualBacklight = INITIAL_BACKLIGHT; 34032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private boolean mChangeInProgress; 34132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 34232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public boolean setState(boolean on, int backlight) { 34332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown synchronized (mLock) { 34432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (on != mPendingOn || backlight != mPendingBacklight) { 34532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (DEBUG) { 34632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown Slog.d(TAG, "Requesting new screen state: on=" + on 34732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown + ", backlight=" + backlight); 34832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 34932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 35032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPendingOn = on; 35132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mPendingBacklight = backlight; 35232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 35332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!mChangeInProgress) { 35432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mChangeInProgress = true; 35532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); 35632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 35732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 35832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown return mChangeInProgress; 3599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 36232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void dump(PrintWriter pw) { 36332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(); 36432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println("Photonic Modulator State:"); 36532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mPendingOn=" + mPendingOn); 36632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mPendingBacklight=" + mPendingBacklight); 36732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mActualOn=" + mActualOn); 36832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mActualBacklight=" + mActualBacklight); 36932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown pw.println(" mChangeInProgress=" + mChangeInProgress); 3709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 37132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 37232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown private final Runnable mTask = new Runnable() { 37332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown @Override 37432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown public void run() { 37532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown // Apply pending changes until done. 37632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown for (;;) { 37732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final boolean on; 37832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final boolean onChanged; 37932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final int backlight; 38032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown final boolean backlightChanged; 38132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown synchronized (mLock) { 38232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown on = mPendingOn; 38332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown onChanged = (on != mActualOn); 38432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown backlight = mPendingBacklight; 38532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown backlightChanged = (backlight != mActualBacklight); 38632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (!onChanged && !backlightChanged) { 38732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mChangeInProgress = false; 38832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown break; 38932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 39032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mActualOn = on; 39132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mActualBacklight = backlight; 39232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 39332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 39432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (DEBUG) { 39532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown Slog.d(TAG, "Updating screen state: on=" + on 39632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown + ", backlight=" + backlight); 39732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 39832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (onChanged && on) { 39932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mDisplayBlanker.unblankAllDisplays(); 40032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 40132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (backlightChanged) { 40232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mBacklight.setBrightness(backlight); 40332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 40432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown if (onChanged && !on) { 40532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown mDisplayBlanker.blankAllDisplays(); 40632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 40732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 40832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown 40932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown // Let the outer class know that all changes have been applied. 41032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown postScreenUpdateThreadSafe(); 41132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 41232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown }; 41332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown } 4149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown} 415