Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28a9a714 authored by Mike Kasick's avatar Mike Kasick
Browse files

Add "Pulse low battery light" switch.

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
parent 83cab8bf
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1890,6 +1890,13 @@ public final class Settings {
         */
        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
+3 −0
Original line number Diff line number Diff line
@@ -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>

+41 −1
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ import android.content.ContentResolver;
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;
@@ -122,6 +124,7 @@ class BatteryService extends Binder {
    private int mDischargeStartLevel;

    private Led mLed;
    private boolean mLedPulseEnabled;

    private boolean mSentLowBatteryBroadcast = false;

@@ -144,6 +147,9 @@ class BatteryService extends Binder {
            mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger");
        }

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

        // set initial status
        update();
    }
@@ -542,6 +548,10 @@ class BatteryService extends Binder {
        }
    }

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

    class Led {
        private LightsService mLightsService;
        private LightsService.Light mBatteryLight;
@@ -582,10 +592,13 @@ class BatteryService extends Binder {
                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) {
@@ -602,5 +615,32 @@ class BatteryService extends Binder {
            }
        }
    }

    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();
            }
        }
    }
}