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