Ensure that dreams show while docked.
Fixed a race between the UiModeManagerService and PowerManagerService
both of which are trying to wake the device when docked / powered.
Bug: 7281240
Change-Id: Ia41fef48f17f2a2eb56549437d295f9a86c95af2
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index d1af2b0..e9e3163 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -37,6 +37,7 @@
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 @@
private NotificationManager mNotificationManager;
private StatusBarManager mStatusBarManager;
+
+ private final PowerManager mPowerManager;
private final PowerManager.WakeLock mWakeLock;
static Intent buildHomeIntent(String category) {
@@ -163,8 +166,8 @@
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 @@
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 f584302..abbae5b 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -1078,41 +1078,51 @@
}
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;
}
/**