Skip to content

Commit

Permalink
Add "Pulse low battery light" switch.
Browse files Browse the repository at this point in the history
Implements the framework portion of an optional "Pulse low battery light"
switch, which allows the pulsing low battery LED to be disabled.  The
function and implementation of this switch is analogous to (and borrowed
from) the "Pulse notification light" switch.

This is motivated by devices (e.g., epicmtd) featuring a battery charging
LED, where the LED does not support pulsing in hardware and relies on a
kernel (CPU) timer to implement the pulse capability.  On these devices,
pulsing the LED requires waking the CPU from suspend on every LED on/off
event, substantially reducing the proportion of time the CPU can suspend,
and thus, substantially increasing power consumption.

Therefore, when the these devices reach the low battery threshold, their
power consumption, ironically, increases measurably in order to pulse the
battery charging LED, which lowers battery life and increases the
likelihood of a low-battery shutdown if the user cannot charge the device
in a timely fashion.  This switch allows the user to disable the pulsing
low battery LED in order to maximize their low battery charge.

Change-Id: I3a5c8938fd7c444c90b2af123e683982c614cd6e
  • Loading branch information
mkasick authored and peteralfonso committed Mar 2, 2012
1 parent 04d6d03 commit ed63fec
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
7 changes: 7 additions & 0 deletions core/java/android/provider/Settings.java
Expand Up @@ -1757,6 +1757,13 @@ public static void setShowGTalkServiceStatus(ContentResolver cr, boolean flag) {
*/
public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";

/**
* Whether the battery LED should repeatedly flash when the battery is low
* on charge. The value is boolean (1 or 0).
* @hide
*/
public static final String BATTERY_LIGHT_PULSE = "battery_light_pulse";

/**
* Show pointer location on screen?
* 0 = no
Expand Down
3 changes: 3 additions & 0 deletions core/res/res/values/config.xml
Expand Up @@ -437,6 +437,9 @@
<!-- Is the notification LED intrusive? Used to decide if there should be a disable option -->
<bool name="config_intrusiveNotificationLed">false</bool>

<!-- Is the battery LED intrusive? Used to decide if there should be a disable option -->
<bool name="config_intrusiveBatteryLed">false</bool>

<!-- Default value for LED off time when the battery is low on charge in miliseconds -->
<integer name="config_notificationsBatteryLedOff">2875</integer>

Expand Down
42 changes: 41 additions & 1 deletion services/java/com/android/server/BatteryService.java
Expand Up @@ -24,9 +24,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
import android.os.DropBoxManager;
import android.os.RemoteException;
Expand Down Expand Up @@ -122,6 +124,7 @@ class BatteryService extends Binder {
private int mDischargeStartLevel;

private Led mLed;
private boolean mLedPulseEnabled;

private boolean mSentLowBatteryBroadcast = false;

Expand All @@ -144,6 +147,9 @@ public BatteryService(Context context, LightsService lights) {
mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger");
}

SettingsObserver observer = new SettingsObserver(new Handler());
observer.observe();

// set initial status
update();
}
Expand Down Expand Up @@ -542,6 +548,10 @@ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
}
}

private synchronized void updateLedPulse() {
mLed.updateLightsLocked();
}

class Led {
private LightsService mLightsService;
private LightsService.Light mBatteryLight;
Expand Down Expand Up @@ -582,10 +592,13 @@ void updateLightsLocked() {
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
// Solid red when battery is charging
mBatteryLight.setColor(mBatteryLowARGB);
} else {
} else if (mLedPulseEnabled) {
// Flash red when battery is low and not charging
mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED,
mBatteryLedOn, mBatteryLedOff);
} else {
// "Pulse low battery light" is disabled, no lights.
mBatteryLight.turnOff();
}
} else if (status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL) {
Expand All @@ -602,5 +615,32 @@ void updateLightsLocked() {
}
}
}

class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
}

void observe() {
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.BATTERY_LIGHT_PULSE), false, this);
update();
}

@Override public void onChange(boolean selfChange) {
update();
}

public void update() {
ContentResolver resolver = mContext.getContentResolver();
boolean pulseEnabled = Settings.System.getInt(resolver,
Settings.System.BATTERY_LIGHT_PULSE, 1) != 0;
if (mLedPulseEnabled != pulseEnabled) {
mLedPulseEnabled = pulseEnabled;
updateLedPulse();
}
}
}
}

0 comments on commit ed63fec

Please sign in to comment.