diff options
-rw-r--r-- | services/java/com/android/server/BatteryService.java | 9 | ||||
-rw-r--r-- | services/java/com/android/server/power/PowerManagerService.java | 59 |
2 files changed, 64 insertions, 4 deletions
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index 4b20a53..0045f4a 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -197,6 +197,15 @@ public final class BatteryService extends Binder { } /** + * Returns the current plug type. + */ + public int getPlugType() { + synchronized (mLock) { + return mPlugType; + } + } + + /** * Returns battery level as a percentage. */ public int getBatteryLevel() { diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index a782d88..2ddda6c 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -135,6 +135,11 @@ public final class PowerManagerService extends IPowerManager.Stub // minimum screen off timeout should be longer than this. private static final int SCREEN_DIM_DURATION = 7 * 1000; + // Upper bound on the battery charge percentage in order to consider turning + // the screen on when the device starts charging wirelessly. + // See point of use for more details. + private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95; + private Context mContext; private LightsService mLightsService; private BatteryService mBatteryService; @@ -218,6 +223,9 @@ public final class PowerManagerService extends IPowerManager.Stub // True if the device is plugged into a power source. private boolean mIsPowered; + // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS. + private int mPlugType; + // True if the device should wake up when plugged or unplugged. private boolean mWakeUpWhenPluggedOrUnpluggedConfig; @@ -1013,15 +1021,19 @@ public final class PowerManagerService extends IPowerManager.Stub */ private void updateIsPoweredLocked(int dirty) { if ((dirty & DIRTY_BATTERY_STATE) != 0) { - boolean wasPowered = mIsPowered; + final boolean wasPowered = mIsPowered; + final int oldPlugType = mPlugType; mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); + mPlugType = mBatteryService.getPlugType(); if (DEBUG) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered - + ", mIsPowered=" + mIsPowered); + + ", mIsPowered=" + mIsPowered + + ", oldPlugType=" + oldPlugType + + ", mPlugType=" + mPlugType); } - if (wasPowered != mIsPowered) { + if (wasPowered != mIsPowered || oldPlugType != mPlugType) { mDirty |= DIRTY_IS_POWERED; // Treat plugging and unplugging the devices as a user activity. @@ -1030,7 +1042,7 @@ public final class PowerManagerService extends IPowerManager.Stub // Some devices also wake the device when plugged or unplugged because // they don't have a charging LED. final long now = SystemClock.uptimeMillis(); - if (mWakeUpWhenPluggedOrUnpluggedConfig) { + if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType)) { wakeUpNoUpdateLocked(now); } userActivityNoUpdateLocked( @@ -1039,6 +1051,44 @@ 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; + } + return false; + } + /** * Updates the value of mStayOn. * Sets DIRTY_STAY_ON if a change occurred. @@ -1891,6 +1941,7 @@ public final class PowerManagerService extends IPowerManager.Stub pw.println(" mDirty=0x" + Integer.toHexString(mDirty)); pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness)); pw.println(" mIsPowered=" + mIsPowered); + pw.println(" mPlugType=" + mPlugType); pw.println(" mStayOn=" + mStayOn); pw.println(" mBootCompleted=" + mBootCompleted); pw.println(" mSystemReady=" + mSystemReady); |