diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java index d1af2b0229ef7..e9e31633f59c8 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/java/com/android/server/UiModeManagerService.java @@ -37,6 +37,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.service.dreams.DreamService; @@ -90,6 +91,8 @@ class UiModeManagerService extends IUiModeManager.Stub { private NotificationManager mNotificationManager; private StatusBarManager mStatusBarManager; + + private final PowerManager mPowerManager; private final PowerManager.WakeLock mWakeLock; static Intent buildHomeIntent(String category) { @@ -163,8 +166,8 @@ class UiModeManagerService extends IUiModeManager.Stub { mContext.registerReceiver(mBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); + mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mConfiguration.setToDefaults(); @@ -502,7 +505,17 @@ class UiModeManagerService extends IUiModeManager.Stub { try { IDreamManager dreamManagerService = IDreamManager.Stub.asInterface( ServiceManager.getService(DreamService.DREAM_SERVICE)); - dreamManagerService.dream(); + if (dreamManagerService != null && !dreamManagerService.isDreaming()) { + // Wake up. + // The power manager will wake up the system when it starts receiving power + // but there is a race between that happening and the UI mode manager + // starting a dream. We want the system to already be awake + // by the time this happens. Otherwise the dream may not start. + mPowerManager.wakeUp(SystemClock.uptimeMillis()); + + // Dream. + dreamManagerService.dream(); + } } catch (RemoteException ex) { Slog.e(TAG, "Could not start dream when docked.", ex); } diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index f58430276fb26..abbae5bb0ad97 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -1078,41 +1078,51 @@ public final class PowerManagerService extends IPowerManager.Stub } private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(boolean wasPowered, int oldPlugType) { - if (mWakeUpWhenPluggedOrUnpluggedConfig) { - // FIXME: Need more accurate detection of wireless chargers. - // - // We are unable to accurately detect whether the device is resting on the - // charger unless it is actually receiving power. This causes us some grief - // because the device might not appear to be plugged into the wireless charger - // unless it actually charging. - // - // To avoid spuriously waking the screen, we apply a special policy to - // wireless chargers. - // - // 1. Don't wake the device when unplugged from wireless charger because - // it might be that the device is still resting on the wireless charger - // but is not receiving power anymore because the battery is full. - // - // 2. Don't wake the device when plugged into a wireless charger if the - // battery already appears to be mostly full. This situation may indicate - // that the device was resting on the charger the whole time and simply - // wasn't receiving power because the battery was full. We can't tell - // whether the device was just placed on the charger or whether it has - // been there for half of the night slowly discharging until it hit - // the point where it needed to start charging again. - if (wasPowered && !mIsPowered - && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { - return false; - } - if (!wasPowered && mIsPowered - && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS - && mBatteryService.getBatteryLevel() >= - WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) { - return false; - } - return true; + // Don't wake when powered unless configured to do so. + if (!mWakeUpWhenPluggedOrUnpluggedConfig) { + return false; } - return false; + + // FIXME: Need more accurate detection of wireless chargers. + // + // We are unable to accurately detect whether the device is resting on the + // charger unless it is actually receiving power. This causes us some grief + // because the device might not appear to be plugged into the wireless charger + // unless it actually charging. + // + // To avoid spuriously waking the screen, we apply a special policy to + // wireless chargers. + // + // 1. Don't wake the device when unplugged from wireless charger because + // it might be that the device is still resting on the wireless charger + // but is not receiving power anymore because the battery is full. + // + // 2. Don't wake the device when plugged into a wireless charger if the + // battery already appears to be mostly full. This situation may indicate + // that the device was resting on the charger the whole time and simply + // wasn't receiving power because the battery was full. We can't tell + // whether the device was just placed on the charger or whether it has + // been there for half of the night slowly discharging until it hit + // the point where it needed to start charging again. + if (wasPowered && !mIsPowered + && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { + return false; + } + if (!wasPowered && mIsPowered + && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS + && mBatteryService.getBatteryLevel() >= + WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) { + return false; + } + + // If already dreaming and becoming powered, then don't wake. + if (mIsPowered && (mWakefulness == WAKEFULNESS_NAPPING + || mWakefulness == WAKEFULNESS_DREAMING)) { + return false; + } + + // Otherwise wake up! + return true; } /**