summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2015-04-10 20:15:01 -0700
committerJeff Brown <jeffbrown@google.com>2015-04-13 01:51:22 -0700
commit5d6443bf7c087167e47ea39b13e6af09cb43ad97 (patch)
tree0415e23f50ea376a96c4b28df732a238bc435f07
parent834a91dda7724974fbd93bc65b9dd7178edddcdd (diff)
downloadframeworks_base-5d6443bf7c087167e47ea39b13e6af09cb43ad97.zip
frameworks_base-5d6443bf7c087167e47ea39b13e6af09cb43ad97.tar.gz
frameworks_base-5d6443bf7c087167e47ea39b13e6af09cb43ad97.tar.bz2
Set initial screen brightness earlier in the boot process.
Previously we had to wait for systemReady before setting the brightness due to the order in which the display power controller was initialized. Unfortunately it could take us a rather long time to reach that stage, particularly after an OTA where the screen would remain at maximum brightness for minutes while "Optimizing Apps". This change moves the brightness backlight setting code deeper into the display manager which has a couple of nice side-benefits in that it now becomes much easier to coordinate display power mode changes with display backlight changes. So this change also resolves some issued with changing the backlight while in DOZE_SUSPEND and ensuring that backlight changes generally end up being performed before executing a power mode change except in the case where the display needs to come out of suspend first. (So now the backlight will be set before entering DOZE from the ON state.) Deleted some dead code in LightService which was in the way. Bug: 19029490 Change-Id: I494b5223e676248daf2ff8be3ec338845977f73c
-rw-r--r--Android.mk1
-rw-r--r--core/java/android/os/IHardwareService.aidl26
-rw-r--r--services/core/java/com/android/server/display/DisplayBlanker.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayDevice.java4
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java48
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerState.java39
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java97
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/lights/LightsService.java48
-rw-r--r--services/java/com/android/server/SystemServer.java6
11 files changed, 139 insertions, 140 deletions
diff --git a/Android.mk b/Android.mk
index 3e049f7..f4b9551 100644
--- a/Android.mk
+++ b/Android.mk
@@ -195,7 +195,6 @@ LOCAL_SRC_FILES += \
core/java/android/os/IBatteryPropertiesListener.aidl \
core/java/android/os/IBatteryPropertiesRegistrar.aidl \
core/java/android/os/ICancellationSignal.aidl \
- core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkActivityListener.aidl \
core/java/android/os/INetworkManagementService.aidl \
diff --git a/core/java/android/os/IHardwareService.aidl b/core/java/android/os/IHardwareService.aidl
deleted file mode 100644
index 38abfc0..0000000
--- a/core/java/android/os/IHardwareService.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/** {@hide} */
-interface IHardwareService
-{
- // obsolete flashlight support
- boolean getFlashlightEnabled();
- void setFlashlightEnabled(boolean on);
-}
-
diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java
index eb0ae6a..816dc13 100644
--- a/services/core/java/com/android/server/display/DisplayBlanker.java
+++ b/services/core/java/com/android/server/display/DisplayBlanker.java
@@ -20,5 +20,5 @@ package com.android.server.display;
* Interface used to update the actual display state.
*/
public interface DisplayBlanker {
- void requestDisplayState(int state);
+ void requestDisplayState(int state, int brightness);
}
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 61631d4..e16be71 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -118,10 +118,12 @@ abstract class DisplayDevice {
/**
* Sets the display state, if supported.
*
+ * @param state The new display state.
+ * @param brightness The new display brightness.
* @return A runnable containing work to be deferred until after we have
* exited the critical section, or null if none.
*/
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
return null;
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5f0ad9f..9ea0444 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -40,11 +40,13 @@ import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -179,7 +181,11 @@ public final class DisplayManagerService extends SystemService {
// The overall display state, independent of changes that might influence one
// display or another in particular.
- private int mGlobalDisplayState = Display.STATE_UNKNOWN;
+ private int mGlobalDisplayState = Display.STATE_ON;
+
+ // The overall display brightness.
+ // For now, this only applies to the built-in display but we may split it up eventually.
+ private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
// Set to true when there are pending display changes that have yet to be applied
// to the surface flinger state.
@@ -226,6 +232,9 @@ public final class DisplayManagerService extends SystemService {
mUiHandler = UiThread.getHandler();
mDisplayAdapterListener = new DisplayAdapterListener();
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
+
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
}
@Override
@@ -322,16 +331,34 @@ public final class DisplayManagerService extends SystemService {
}
}
- private void requestGlobalDisplayStateInternal(int state) {
+ private void requestGlobalDisplayStateInternal(int state, int brightness) {
+ if (state == Display.STATE_UNKNOWN) {
+ state = Display.STATE_ON;
+ }
+ if (state == Display.STATE_OFF) {
+ brightness = PowerManager.BRIGHTNESS_OFF;
+ } else if (brightness < 0) {
+ brightness = PowerManager.BRIGHTNESS_DEFAULT;
+ } else if (brightness > PowerManager.BRIGHTNESS_ON) {
+ brightness = PowerManager.BRIGHTNESS_ON;
+ }
+
synchronized (mTempDisplayStateWorkQueue) {
try {
// Update the display state within the lock.
synchronized (mSyncRoot) {
- if (mGlobalDisplayState != state) {
- mGlobalDisplayState = state;
- updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
- scheduleTraversalLocked(false);
+ if (mGlobalDisplayState == state
+ && mGlobalDisplayBrightness == brightness) {
+ return; // no change
}
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
+ + Display.stateToString(state)
+ + ", brightness=" + brightness + ")");
+ mGlobalDisplayState = state;
+ mGlobalDisplayBrightness = brightness;
+ updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
+ scheduleTraversalLocked(false);
}
// Setting the display power state can take hundreds of milliseconds
@@ -341,6 +368,7 @@ public final class DisplayManagerService extends SystemService {
for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
mTempDisplayStateWorkQueue.get(i).run();
}
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
} finally {
mTempDisplayStateWorkQueue.clear();
}
@@ -708,7 +736,7 @@ public final class DisplayManagerService extends SystemService {
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
- return device.requestDisplayStateLocked(mGlobalDisplayState);
+ return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
}
return null;
}
@@ -1462,16 +1490,16 @@ public final class DisplayManagerService extends SystemService {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
- public void requestDisplayState(int state) {
+ public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
}
};
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cf1f4b0..f74601e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -19,7 +19,6 @@ package com.android.server.display;
import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.LightsManager;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -122,9 +121,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Battery stats.
private final IBatteryStats mBatteryStats;
- // The lights service.
- private final LightsManager mLights;
-
// The sensor manager.
private final SensorManager mSensorManager;
@@ -260,7 +256,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
- mLights = LocalServices.getService(LightsManager.class);
mSensorManager = sensorManager;
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
@@ -443,7 +438,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Initialize the power state object for the default display.
// In the future, we might manage multiple displays independently.
mPowerState = new DisplayPowerState(mBlanker,
- mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
new ColorFade(Display.DEFAULT_DISPLAY));
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index a3c9738..f53ccc9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -16,13 +16,10 @@
package com.android.server.display;
-import com.android.server.lights.Light;
-
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.Trace;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Slog;
@@ -56,7 +53,6 @@ final class DisplayPowerState {
private final Handler mHandler;
private final Choreographer mChoreographer;
private final DisplayBlanker mBlanker;
- private final Light mBacklight;
private final ColorFade mColorFade;
private final PhotonicModulator mPhotonicModulator;
@@ -72,12 +68,11 @@ final class DisplayPowerState {
private Runnable mCleanListener;
- public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
+ public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
mHandler = new Handler(true /*async*/);
mChoreographer = Choreographer.getInstance();
mBlanker = blanker;
- mBacklight = backlight;
- mColorFade = electronBeam;
+ mColorFade = colorFade;
mPhotonicModulator = new PhotonicModulator();
mPhotonicModulator.start();
@@ -415,35 +410,7 @@ final class DisplayPowerState {
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
- boolean suspending = Display.isSuspendedState(state);
- if (stateChanged && !suspending) {
- requestDisplayState(state);
- }
- if (backlightChanged) {
- setBrightness(backlight);
- }
- if (stateChanged && suspending) {
- requestDisplayState(state);
- }
- }
- }
-
- private void requestDisplayState(int state) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ")");
- try {
- mBlanker.requestDisplayState(state);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
-
- private void setBrightness(int backlight) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
- try {
- mBacklight.setBrightness(backlight);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ mBlanker.requestDisplayState(state, backlight);
}
}
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 5ebe64d..e87f265 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,10 +16,15 @@
package com.android.server.display;
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.Slog;
@@ -40,6 +45,7 @@ import java.util.Arrays;
*/
final class LocalDisplayAdapter extends DisplayAdapter {
private static final String TAG = "LocalDisplayAdapter";
+ private static final boolean DEBUG = false;
private static final String UNIQUE_ID_PREFIX = "local:";
@@ -132,14 +138,17 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final int mBuiltInDisplayId;
private final SurfaceControl.PhysicalDisplayInfo mPhys;
private final int mDefaultPhysicalDisplayInfo;
+ private final Light mBacklight;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
+ private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
private float[] mSupportedRefreshRates;
private int[] mRefreshRateConfigIndices;
private float mLastRequestedRefreshRate;
+
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
@@ -148,6 +157,13 @@ final class LocalDisplayAdapter extends DisplayAdapter {
physicalDisplayInfos[activeDisplayInfo]);
mDefaultPhysicalDisplayInfo = activeDisplayInfo;
updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
+
+ if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ LightsManager lights = LocalServices.getService(LightsManager.class);
+ mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
+ } else {
+ mBacklight = null;
+ }
}
public boolean updatePhysicalDisplayInfoLocked(
@@ -225,28 +241,91 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@Override
- public Runnable requestDisplayStateLocked(final int state) {
- if (mState != state) {
+ public Runnable requestDisplayStateLocked(final int state, final int brightness) {
+ // Assume that the brightness is off if the display is being turned off.
+ assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
+
+ final boolean stateChanged = (mState != state);
+ final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
+ if (stateChanged || brightnessChanged) {
final int displayId = mBuiltInDisplayId;
final IBinder token = getDisplayTokenLocked();
- final int mode = getPowerModeForState(state);
- mState = state;
- updateDeviceInfoLocked();
+ final int oldState = mState;
+
+ if (stateChanged) {
+ mState = state;
+ updateDeviceInfoLocked();
+ }
- // Defer actually setting the display power mode until we have exited
+ if (brightnessChanged) {
+ mBrightness = brightness;
+ }
+
+ // Defer actually setting the display state until after we have exited
// the critical section since it can take hundreds of milliseconds
// to complete.
return new Runnable() {
@Override
public void run() {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ", id=" + displayId + ")");
+ // Exit a suspended state before making any changes.
+ int currentState = oldState;
+ if (Display.isSuspendedState(oldState)
+ || oldState == Display.STATE_UNKNOWN) {
+ if (!Display.isSuspendedState(state)) {
+ setDisplayState(state);
+ currentState = state;
+ } else if (state == Display.STATE_DOZE_SUSPEND
+ || oldState == Display.STATE_DOZE_SUSPEND) {
+ setDisplayState(Display.STATE_DOZE);
+ currentState = Display.STATE_DOZE;
+ } else {
+ return; // old state and new state is off
+ }
+ }
+
+ // Apply brightness changes given that we are in a non-suspended state.
+ if (brightnessChanged) {
+ setDisplayBrightness(brightness);
+ }
+
+ // Enter the final desired state, possibly suspended.
+ if (state != currentState) {
+ setDisplayState(state);
+ }
+ }
+
+ private void setDisplayState(int state) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
try {
+ final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
+
+ private void setDisplayBrightness(int brightness) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ try {
+ mBacklight.setBrightness(brightness);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ }
};
}
return null;
@@ -278,6 +357,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
pw.println("mPhys=" + mPhys);
pw.println("mState=" + Display.stateToString(mState));
+ pw.println("mBrightness=" + mBrightness);
+ pw.println("mBacklight=" + mBacklight);
}
private void updateDeviceInfoLocked() {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f181cd5..6f59b54 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -221,7 +221,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
}
@Override
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 2da9d8e..ed884ef 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -19,16 +19,11 @@ package com.android.server.lights;
import com.android.server.SystemService;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.Handler;
-import android.os.IHardwareService;
import android.os.Message;
import android.os.Trace;
import android.util.Slog;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
public class LightsService extends SystemService {
static final String TAG = "LightsService";
static final boolean DEBUG = false;
@@ -124,46 +119,6 @@ public class LightsService extends SystemService {
private boolean mFlashing;
}
- /* This class implements an obsolete API that was removed after eclair and re-added during the
- * final moments of the froyo release to support flashlight apps that had been using the private
- * IHardwareService API. This is expected to go away in the next release.
- */
- private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
-
- private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
-
- public boolean getFlashlightEnabled() {
- try {
- FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
- int result = fis.read();
- fis.close();
- return (result != '0');
- } catch (Exception e) {
- return false;
- }
- }
-
- public void setFlashlightEnabled(boolean on) {
- final Context context = getContext();
- if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
- != PackageManager.PERMISSION_GRANTED &&
- context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
- }
- try {
- FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
- byte[] bytes = new byte[2];
- bytes[0] = (byte)(on ? '1' : '0');
- bytes[1] = '\n';
- fos.write(bytes);
- fos.close();
- } catch (Exception e) {
- // fail silently
- }
- }
- };
-
public LightsService(Context context) {
super(context);
@@ -176,13 +131,12 @@ public class LightsService extends SystemService {
@Override
public void onStart() {
- publishBinderService("hardware", mLegacyFlashlightHack);
publishLocalService(LightsManager.class, mService);
}
private final LightsManager mService = new LightsManager() {
@Override
- public com.android.server.lights.Light getLight(int id) {
+ public Light getLight(int id) {
if (id < LIGHT_ID_COUNT) {
return mLights[id];
} else {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 53da75b..593853c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -325,6 +325,9 @@ public final class SystemServer {
// initialize power management features.
mActivityManagerService.initPowerManagement();
+ // Manages LEDs and display backlight so we need it to bring up the display.
+ mSystemServiceManager.startService(LightsService.class);
+
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
@@ -363,9 +366,6 @@ public final class SystemServer {
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
- // Manages LEDs and display backlight.
- mSystemServiceManager.startService(LightsService.class);
-
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);