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
19182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinskiimport com.android.server.lights.Light;
2032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
210839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentineimport android.content.Context;
2232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport android.os.AsyncTask;
2332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brownimport android.os.Handler;
249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Looper;
259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.PowerManager;
263edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brownimport android.os.Trace;
279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.FloatProperty;
289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.IntProperty;
299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.Slog;
309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.Choreographer;
31037c33eae74bee2774897d969d48947f9abe254fJeff Brownimport android.view.Display;
329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport java.io.PrintWriter;
349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/**
3632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * Controls the display power state.
3732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * <p>
38ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * This component is similar in nature to a {@link android.view.View} except that it
39ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * describes the properties of a display.  When properties are changed, the component
4032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * invalidates itself and posts a callback to apply the changes in a consistent order.
4132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * This mechanism enables multiple properties of the display power state to be animated
4232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * together smoothly by the animation framework.  Some of the work to blank or unblank
4332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * the display is done on a separate thread to avoid blocking the looper.
4432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p><p>
459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This component must only be created or accessed by the {@link Looper} thread
469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * that belongs to the {@link DisplayPowerController}.
4732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p><p>
489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * We don't need to worry about holding a suspend blocker here because the
49ad9ef191f50767d8d5b6f0fbd4b59bb1400dcd25Jeff Brown * power manager does that for us whenever there is a change in progress.
5032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown * </p>
519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */
529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownfinal class DisplayPowerState {
539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static final String TAG = "DisplayPowerState";
549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private static boolean DEBUG = false;
569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
5732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private final Handler mHandler;
589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private final Choreographer mChoreographer;
59037c33eae74bee2774897d969d48947f9abe254fJeff Brown    private final DisplayBlanker mBlanker;
60182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    private final Light mBacklight;
610839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private final ColorFade mColorFade;
6232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private final PhotonicModulator mPhotonicModulator;
639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
64037c33eae74bee2774897d969d48947f9abe254fJeff Brown    private int mScreenState;
659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private int mScreenBrightness;
6632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private boolean mScreenReady;
6732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private boolean mScreenUpdatePending;
6832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
690839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private boolean mColorFadePrepared;
700839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private float mColorFadeLevel;
710839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private boolean mColorFadeReady;
720839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private boolean mColorFadeDrawPending;
739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    private Runnable mCleanListener;
759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
760839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
7732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mHandler = new Handler(true /*async*/);
789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mChoreographer = Choreographer.getInstance();
79037c33eae74bee2774897d969d48947f9abe254fJeff Brown        mBlanker = blanker;
8032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mBacklight = backlight;
810839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFade = electronBeam;
8232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mPhotonicModulator = new PhotonicModulator();
830a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        mPhotonicModulator.start();
849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
85f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // At boot time, we know that the screen is on and the electron beam
86f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // animation is not playing.  We don't know the screen's brightness though,
87f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // so prepare to set it to a known state when the state is next applied.
88f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // Although we set the brightness to full on here, the display power controller
89f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // will reset the brightness to a new level immediately before the changes
90f75724b3d36d84c881d4052cfd4be766d454c98fJeff Brown        // actually have a chance to be applied.
91037c33eae74bee2774897d969d48947f9abe254fJeff Brown        mScreenState = Display.STATE_ON;
929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        mScreenBrightness = PowerManager.BRIGHTNESS_ON;
9332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        scheduleScreenUpdate();
9432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
950839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadePrepared = false;
960839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadeLevel = 1.0f;
970839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadeReady = true;
989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1000839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL =
1019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            new FloatProperty<DisplayPowerState>("electronBeamLevel") {
1029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
1039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void setValue(DisplayPowerState object, float value) {
1040839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            object.setColorFadeLevel(value);
1059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
1069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
1089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public Float get(DisplayPowerState object) {
1090839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            return object.getColorFadeLevel();
1109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
1119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
1129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
1149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            new IntProperty<DisplayPowerState>("screenBrightness") {
1159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
1169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public void setValue(DisplayPowerState object, int value) {
1179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            object.setScreenBrightness(value);
1189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
1199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        @Override
1219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        public Integer get(DisplayPowerState object) {
1229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return object.getScreenBrightness();
1239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
1249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    };
1259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
127037c33eae74bee2774897d969d48947f9abe254fJeff Brown     * Sets whether the screen is on, off, or dozing.
1289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
129037c33eae74bee2774897d969d48947f9abe254fJeff Brown    public void setScreenState(int state) {
130037c33eae74bee2774897d969d48947f9abe254fJeff Brown        if (mScreenState != state) {
1319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (DEBUG) {
132037c33eae74bee2774897d969d48947f9abe254fJeff Brown                Slog.d(TAG, "setScreenState: state=" + state);
1339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
1349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
135037c33eae74bee2774897d969d48947f9abe254fJeff Brown            mScreenState = state;
13632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            mScreenReady = false;
13732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            scheduleScreenUpdate();
1389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
1399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
1409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
142037c33eae74bee2774897d969d48947f9abe254fJeff Brown     * Gets the desired screen state.
1439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
144037c33eae74bee2774897d969d48947f9abe254fJeff Brown    public int getScreenState() {
145037c33eae74bee2774897d969d48947f9abe254fJeff Brown        return mScreenState;
1469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
1479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
14932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     * Sets the display brightness.
15032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     *
15132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     * @param brightness The brightness, ranges from 0 (minimum / off) to 255 (brightest).
15232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     */
15332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    public void setScreenBrightness(int brightness) {
15432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        if (mScreenBrightness != brightness) {
15532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            if (DEBUG) {
15632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
15732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            }
15832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
15932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            mScreenBrightness = brightness;
160037c33eae74bee2774897d969d48947f9abe254fJeff Brown            if (mScreenState != Display.STATE_OFF) {
16132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                mScreenReady = false;
16232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                scheduleScreenUpdate();
16332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            }
16432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
16532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
16632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
16732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    /**
16832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     * Gets the screen brightness.
16932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     */
17032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    public int getScreenBrightness() {
17132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        return mScreenBrightness;
17232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
17332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
17432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    /**
1759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Prepares the electron beam to turn on or off.
1769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * This method should be called before starting an animation because it
1779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * can take a fair amount of time to prepare the electron beam surface.
1789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     *
1798b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown     * @param mode The electron beam animation mode to prepare.
1809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * @return True if the electron beam was prepared.
1819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
1820839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public boolean prepareColorFade(Context context, int mode) {
1830839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        if (!mColorFade.prepare(context, mode)) {
1840839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadePrepared = false;
1850839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadeReady = true;
18632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            return false;
18732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
18832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
1890839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadePrepared = true;
1900839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadeReady = false;
1910839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        scheduleColorFadeDraw();
19232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        return true;
1939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
1949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
1959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
1969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Dismisses the electron beam surface.
1979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
1980839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public void dismissColorFade() {
1990839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFade.dismiss();
2000839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadePrepared = false;
2010839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFadeReady = true;
2029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
2039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
2059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Sets the level of the electron beam steering current.
2069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     *
2079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * The display is blanked when the level is 0.0.  In normal use, the electron
2089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * beam should have a value of 1.0.  The electron beam is unstable in between
2099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * these states and the picture quality may be compromised.  For best effect,
2109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * the electron beam should be warmed up or cooled off slowly.
2119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     *
2129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Warning: Electron beam emits harmful radiation.  Avoid direct exposure to
2139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * skin or eyes.
2149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     *
2159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * @param level The level, ranges from 0.0 (full off) to 1.0 (full on).
2169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
2170839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public void setColorFadeLevel(float level) {
2180839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        if (mColorFadeLevel != level) {
2199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (DEBUG) {
2200839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                Slog.d(TAG, "setColorFadeLevel: level=" + level);
2219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
2229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2230839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadeLevel = level;
224037c33eae74bee2774897d969d48947f9abe254fJeff Brown            if (mScreenState != Display.STATE_OFF) {
22532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                mScreenReady = false;
22632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                scheduleScreenUpdate(); // update backlight brightness
22732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            }
2280839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            if (mColorFadePrepared) {
2290839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                mColorFadeReady = false;
2300839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                scheduleColorFadeDraw();
23132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            }
2329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
2339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
2349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
2369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Gets the level of the electron beam steering current.
2379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
2380839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    public float getColorFadeLevel() {
2390839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        return mColorFadeLevel;
2409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
2419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    /**
2439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Returns true if no properties have been invalidated.
2449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * Otherwise, returns false and promises to invoke the specified listener
2459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * when the properties have all been applied.
2469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     * The listener always overrides any previously set listener.
2479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown     */
2489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public boolean waitUntilClean(Runnable listener) {
2490839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        if (!mScreenReady || !mColorFadeReady) {
2509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mCleanListener = listener;
2519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return false;
2529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        } else {
2539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mCleanListener = null;
2549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            return true;
2559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
2569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
2579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
2589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public void dump(PrintWriter pw) {
2599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println();
2609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("Display Power State:");
261037c33eae74bee2774897d969d48947f9abe254fJeff Brown        pw.println("  mScreenState=" + Display.stateToString(mScreenState));
2629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        pw.println("  mScreenBrightness=" + mScreenBrightness);
26332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        pw.println("  mScreenReady=" + mScreenReady);
26432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        pw.println("  mScreenUpdatePending=" + mScreenUpdatePending);
2650839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        pw.println("  mColorFadePrepared=" + mColorFadePrepared);
2660839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        pw.println("  mColorFadeLevel=" + mColorFadeLevel);
2670839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        pw.println("  mColorFadeReady=" + mColorFadeReady);
2680839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        pw.println("  mColorFadeDrawPending=" + mColorFadeDrawPending);
2699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
27032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mPhotonicModulator.dump(pw);
2710839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        mColorFade.dump(pw);
2729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
2739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
27432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private void scheduleScreenUpdate() {
27532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        if (!mScreenUpdatePending) {
27632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            mScreenUpdatePending = true;
27732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            postScreenUpdateThreadSafe();
27832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
27932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
28032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
28132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private void postScreenUpdateThreadSafe() {
28232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mHandler.removeCallbacks(mScreenUpdateRunnable);
28332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        mHandler.post(mScreenUpdateRunnable);
28432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
28532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
2860839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private void scheduleColorFadeDraw() {
2870839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        if (!mColorFadeDrawPending) {
2880839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadeDrawPending = true;
2899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,
2900839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                    mColorFadeDrawRunnable, null);
2919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
29232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
2939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
29432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private void invokeCleanListenerIfNeeded() {
29532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        final Runnable listener = mCleanListener;
2960839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine        if (listener != null && mScreenReady && mColorFadeReady) {
29732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            mCleanListener = null;
29832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            listener.run();
29932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
3009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
3019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
30232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    private final Runnable mScreenUpdateRunnable = new Runnable() {
30332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        @Override
30432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        public void run() {
30532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            mScreenUpdatePending = false;
3069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
307037c33eae74bee2774897d969d48947f9abe254fJeff Brown            int brightness = mScreenState != Display.STATE_OFF
3080839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                    && mColorFadeLevel > 0f ? mScreenBrightness : 0;
309037c33eae74bee2774897d969d48947f9abe254fJeff Brown            if (mPhotonicModulator.setState(mScreenState, brightness)) {
3102d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                if (DEBUG) {
3112d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                    Slog.d(TAG, "Screen ready");
3122d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                }
31332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                mScreenReady = true;
31432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                invokeCleanListenerIfNeeded();
3152d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown            } else {
3162d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                if (DEBUG) {
3172d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                    Slog.d(TAG, "Screen not ready");
3182d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                }
3199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
32032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
32132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    };
3229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3230839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine    private final Runnable mColorFadeDrawRunnable = new Runnable() {
32432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        @Override
32532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        public void run() {
3260839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadeDrawPending = false;
3279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3280839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            if (mColorFadePrepared) {
3290839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine                mColorFade.draw(mColorFadeLevel);
330735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown            }
331735f740fe81b7172d0b208d584eecf632533ec4aJeff Brown
3320839adb25c6d1a9f4e06fc5a098ffd03c67dbe99Michael Lentine            mColorFadeReady = true;
33332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            invokeCleanListenerIfNeeded();
33432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        }
33532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    };
3369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
33732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    /**
33832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     * Updates the state of the screen and backlight asynchronously on a separate thread.
33932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown     */
3400a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown    private final class PhotonicModulator extends Thread {
341037c33eae74bee2774897d969d48947f9abe254fJeff Brown        private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
34232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        private static final int INITIAL_BACKLIGHT = -1; // unknown
34332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
34432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        private final Object mLock = new Object();
34532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
346037c33eae74bee2774897d969d48947f9abe254fJeff Brown        private int mPendingState = INITIAL_SCREEN_STATE;
34732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        private int mPendingBacklight = INITIAL_BACKLIGHT;
348037c33eae74bee2774897d969d48947f9abe254fJeff Brown        private int mActualState = INITIAL_SCREEN_STATE;
34932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        private int mActualBacklight = INITIAL_BACKLIGHT;
35032dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        private boolean mChangeInProgress;
35132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
352037c33eae74bee2774897d969d48947f9abe254fJeff Brown        public boolean setState(int state, int backlight) {
35332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            synchronized (mLock) {
354037c33eae74bee2774897d969d48947f9abe254fJeff Brown                if (state != mPendingState || backlight != mPendingBacklight) {
35532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    if (DEBUG) {
356037c33eae74bee2774897d969d48947f9abe254fJeff Brown                        Slog.d(TAG, "Requesting new screen state: state="
357037c33eae74bee2774897d969d48947f9abe254fJeff Brown                                + Display.stateToString(state) + ", backlight=" + backlight);
35832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    }
35932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
360037c33eae74bee2774897d969d48947f9abe254fJeff Brown                    mPendingState = state;
36132dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    mPendingBacklight = backlight;
36232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
36332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    if (!mChangeInProgress) {
36432dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                        mChangeInProgress = true;
3650a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        mLock.notifyAll();
36632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    }
36732dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                }
3682d8a3908d2b0a74ccdecd97e86e7bfda1caa218eJeff Brown                return !mChangeInProgress;
3699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
3709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
3719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
37232dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown        public void dump(PrintWriter pw) {
3730a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            synchronized (mLock) {
3740a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println();
3750a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("Photonic Modulator State:");
3760a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("  mPendingState=" + Display.stateToString(mPendingState));
3770a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("  mPendingBacklight=" + mPendingBacklight);
3780a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("  mActualState=" + Display.stateToString(mActualState));
3790a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("  mActualBacklight=" + mActualBacklight);
3800a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                pw.println("  mChangeInProgress=" + mChangeInProgress);
3810a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            }
3829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
38332dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
3840a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        @Override
3850a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        public void run() {
3860a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            for (;;) {
3870a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                // Get pending change.
3880a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                final int state;
3890a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                final boolean stateChanged;
3900a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                final int backlight;
3910a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                final boolean backlightChanged;
3920a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                synchronized (mLock) {
3930a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    state = mPendingState;
3940a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    stateChanged = (state != mActualState);
3950a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    backlight = mPendingBacklight;
3960a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    backlightChanged = (backlight != mActualBacklight);
3970a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    if (!stateChanged && !backlightChanged) {
3980a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        // All changed applied, notify outer class and wait for more.
3990a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        mChangeInProgress = false;
4000a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        postScreenUpdateThreadSafe();
4010a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        try {
4020a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                            mLock.wait();
4030a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        } catch (InterruptedException ex) { }
4040a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                        continue;
40532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                    }
4060a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    mActualState = state;
4070a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    mActualBacklight = backlight;
40832dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown                }
40932dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown
4100a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                // Apply pending change.
4110a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                if (DEBUG) {
4120a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    Slog.d(TAG, "Updating screen state: state="
4130a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                            + Display.stateToString(state) + ", backlight=" + backlight);
4140a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                }
4150a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                boolean suspending = Display.isSuspendedState(state);
4160a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                if (stateChanged && !suspending) {
4170a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    requestDisplayState(state);
4180a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                }
4190a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                if (backlightChanged) {
4200a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    setBrightness(backlight);
4210a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                }
4220a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                if (stateChanged && suspending) {
4230a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    requestDisplayState(state);
4240a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                }
42532dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown            }
4260a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        }
4273edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown
4280a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        private void requestDisplayState(int state) {
4290a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
4300a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                    + Display.stateToString(state) + ")");
4310a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            try {
4320a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                mBlanker.requestDisplayState(state);
4330a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            } finally {
4340a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                Trace.traceEnd(Trace.TRACE_TAG_POWER);
4353edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown            }
4360a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        }
4373edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown
4380a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        private void setBrightness(int backlight) {
4390a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
4400a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            try {
4410a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                mBacklight.setBrightness(backlight);
4420a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown            } finally {
4430a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown                Trace.traceEnd(Trace.TRACE_TAG_POWER);
4443edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brown            }
4450a434776b836f8fbea1f84b7bfe158b4ddafc876Jeff Brown        }
44632dafe25ac2e06f127f48d6a5826537e11575f52Jeff Brown    }
4479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown}
448