summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/java/com/android/server/BatteryService.java9
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java59
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);