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

Commit 4ca7f1e2 authored by Joe Onorato's avatar Joe Onorato
Browse files

Implement reminder power dialog and invalid charger dialog.

Bug: 2510318
Bug: 2974431
Change-Id: I92eb419eeffb657e5572a35a490735a96b303d6b
parent 31b2610d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public class BatteryManager {

    /**
     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
     * Boolean value set to true if an unsupported charger is attached
     * Int value set to nonzero if an unsupported charger is attached
     * to the device.
     * {@hide}
     */
+5 −0
Original line number Diff line number Diff line
@@ -290,6 +290,11 @@

    <bool name="config_use_strict_phone_number_comparation">false</bool>

    <!-- Display low battery warning when battery level dips to this value.
         Also, the battery stats are flushed to disk when we hit this level.  -->
    <integer name="config_criticalBatteryWarningLevel">4</integer>

    <!-- Display low battery warning when battery level dips to this value -->
    <!-- Display low battery warning when battery level dips to this value -->
    <integer name="config_lowBatteryWarningLevel">15</integer>

+10 −4
Original line number Diff line number Diff line
@@ -53,11 +53,17 @@
    <string name="battery_low_title">Please connect charger</string>

    <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. -->
    <string name="battery_low_subtitle">The battery is getting low:</string>
    <string name="battery_low_subtitle">The battery is getting low.</string>

    <!-- A message that appears when the battery level is getting low in a dialog.  This is appened to the subtitle of the low battery alert. -->
    <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g>
    or less remaining.</string>
    <!-- A message that appears when the battery level is getting low in a dialog.  This is
        appened to the subtitle of the low battery alert. -->
    <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g> remaining</string>

    <!-- A message that appears when a USB charger is plugged in and the device does not
    support charging on it.  That is, a charger that fits into the USB port and goes into
    a wall socket, not into a computer. (This happens because some devices require more
    current than the USB spec allows.  -->
    <string name="invalid_charger">USB charging not supported.\nUse only the supplied charger.</string>

    <!-- When the battery is low, this is the label of the button to go to the
         power usage activity to find out what drained the battery. -->
+165 −61
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Handler;
import android.media.AudioManager;
import android.media.Ringtone;
@@ -46,32 +47,116 @@ public class PowerUI extends SystemUI {

    Handler mHandler = new Handler();

    int mBatteryLevel = 100;
    int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
    int mPlugType = 0;
    int mInvalidCharger = 0;

    int mLowBatteryAlertCloseLevel;
    int[] mLowBatteryReminderLevels = new int[2];

    AlertDialog mInvalidChargerDialog;
    AlertDialog mLowBatteryDialog;
    int mBatteryLevel;
    TextView mBatteryLevelTextView;

    public void start() {

        mLowBatteryAlertCloseLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
        mLowBatteryReminderLevels[0] = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        mLowBatteryReminderLevels[1] = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_criticalBatteryWarningLevel);

        // Register for Intent broadcasts for...
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        filter.addAction(Intent.ACTION_BATTERY_LOW);
        filter.addAction(Intent.ACTION_BATTERY_OKAY);
        filter.addAction(Intent.ACTION_POWER_CONNECTED);
        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
    }

    /**
     * Buckets the battery level.
     *
     * The code in this function is a little weird because I couldn't comprehend
     * the bucket going up when the battery level was going down. --joeo
     *
     * 1 means that the battery is "ok"
     * 0 means that the battery is between "ok" and what we should warn about.
     * less than 0 means that the battery is low
     */
    private int findBatteryLevelBucket(int level) {
        if (level >= mLowBatteryAlertCloseLevel) {
            return 1;
        }
        if (level >= mLowBatteryReminderLevels[0]) {
            return 0;
        }
        final int N = mLowBatteryReminderLevels.length;
        for (int i=N-1; i>=0; i--) {
            if (level <= mLowBatteryReminderLevels[i]) {
                return -1-i;
            }
        }
        throw new RuntimeException("not possible!");
    }

    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                mBatteryLevel = intent.getIntExtra("level", -1);
            } else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
                final int oldBatteryLevel = mBatteryLevel;
                mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
                final int oldBatteryStatus = mBatteryStatus;
                mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
                        BatteryManager.BATTERY_STATUS_UNKNOWN);
                final int oldPlugType = mPlugType;
                mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
                final int oldInvalidCharger = mInvalidCharger;
                mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);

                final boolean plugged = mPlugType != 0;
                final boolean oldPlugged = oldPlugType != 0;

                int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
                int bucket = findBatteryLevelBucket(mBatteryLevel);

                if (false) {
                    Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
                            + " .. " + mLowBatteryReminderLevels[0]
                            + " .. " + mLowBatteryReminderLevels[1]);
                    Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
                    Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
                    Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
                    Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
                    Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
                    Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
                }

                if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
                    Slog.d(TAG, "showing invalid charger warning");
                    showInvalidChargerDialog();
                    return;
                } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
                    Slog.d(TAG, "closing invalid charger warning");
                    dismissInvalidChargerDialog();
                } else if (mInvalidChargerDialog != null) {
                    // if invalid charger is showing, don't show low battery
                    return;
                }

                if (!plugged
                        && (bucket < oldBucket || oldPlugged)
                        && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                        && bucket < 0) {
                    Slog.d(TAG, "showing low battery warning: level=" + mBatteryLevel);
                    showLowBatteryWarning();
                } else if (plugged || (bucket > oldBucket && bucket > 0)) {
                    Slog.d(TAG, "closing low battery warning: level=" + mBatteryLevel);
                    dismissLowBatteryWarning();
                } else if (mBatteryLevelTextView != null) {
                    showLowBatteryWarning();
            } else if (action.equals(Intent.ACTION_BATTERY_OKAY)
                    || action.equals(Intent.ACTION_POWER_CONNECTED)) {
                if (mLowBatteryDialog != null) {
                    mLowBatteryDialog.dismiss();
                }
            } else {
                Slog.w(TAG, "unknown intent: " + intent);
@@ -79,6 +164,12 @@ public class PowerUI extends SystemUI {
        }
    };

    void dismissLowBatteryWarning() {
        if (mLowBatteryDialog != null) {
            mLowBatteryDialog.dismiss();
        }
    }

    void showLowBatteryWarning() {
        CharSequence levelText = mContext.getString(
                R.string.battery_low_percent_format, mBatteryLevel);
@@ -116,7 +207,12 @@ public class PowerUI extends SystemUI {
            }

            AlertDialog d = b.create();
            d.setOnDismissListener(mLowBatteryListener);
            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    public void onDismiss(DialogInterface dialog) {
                        mLowBatteryDialog = null;
                        mBatteryLevelTextView = null;
                    }
                });
            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            d.show();
            mLowBatteryDialog = d;
@@ -141,45 +237,53 @@ if (false) { // getRingtone ANRs
}
    }

    private DialogInterface.OnDismissListener mLowBatteryListener
            = new DialogInterface.OnDismissListener() {
    void dismissInvalidChargerDialog() {
        if (mInvalidChargerDialog != null) {
            mInvalidChargerDialog.dismiss();
        }
    }

    void showInvalidChargerDialog() {
        dismissLowBatteryWarning();

        AlertDialog.Builder b = new AlertDialog.Builder(mContext);
            b.setCancelable(true);
            b.setMessage(mContext.getString(R.string.invalid_charger));
            b.setIcon(android.R.drawable.ic_dialog_alert);
            b.setPositiveButton(android.R.string.ok, null);

        AlertDialog d = b.create();
            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    public void onDismiss(DialogInterface dialog) {
            mLowBatteryDialog = null;
                        mInvalidChargerDialog = null;
                        mBatteryLevelTextView = null;
                    }
    };
                });

        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        d.show();
        mInvalidChargerDialog = d;
    }
    
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (false) {
            pw.println("args=" + Arrays.toString(args));
        }
        if (args == null || args.length == 0) {
        pw.print("mLowBatteryAlertCloseLevel=");
        pw.println(mLowBatteryAlertCloseLevel);
        pw.print("mLowBatteryReminderLevels=");
        pw.println(Arrays.toString(mLowBatteryReminderLevels));
        pw.print("mInvalidChargerDialog=");
        pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
        pw.print("mLowBatteryDialog=");
        pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
        pw.print("mBatteryLevel=");
        pw.println(Integer.toString(mBatteryLevel));
        }

        // DO NOT SUBMIT with this turned on.
        if (false) {
            if (args.length == 3 && "level".equals(args[1])) {
                try {
                    final int level = Integer.parseInt(args[2]);
                    Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
                    intent.putExtra("level", level);
                    mIntentReceiver.onReceive(mContext, intent);
                } catch (NumberFormatException ex) {
                    pw.println(ex);
                }
            } else if (args.length == 2 && "low".equals(args[1])) {
                Intent intent = new Intent(Intent.ACTION_BATTERY_LOW);
                mIntentReceiver.onReceive(mContext, intent);
            } else if (args.length == 2 && "ok".equals(args[1])) {
                Intent intent = new Intent(Intent.ACTION_BATTERY_OKAY);
                mIntentReceiver.onReceive(mContext, intent);
            }
        }
        pw.print("mBatteryStatus=");
        pw.println(Integer.toString(mBatteryStatus));
        pw.print("mPlugType=");
        pw.println(Integer.toString(mPlugType));
        pw.print("mInvalidCharger=");
        pw.println(Integer.toString(mInvalidCharger));
        pw.print("bucket: ");
        pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
    }
}
+54 −19
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;


/**
@@ -76,7 +77,7 @@ class BatteryService extends Binder {

    // Used locally for determining when to make a last ditch effort to log
    // discharge stats before the device dies.
    private static final int CRITICAL_BATTERY_LEVEL = 4;
    private int mCriticalBatteryLevel;

    private static final int DUMP_MAX_LENGTH = 24 * 1024;
    private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "-u" };
@@ -100,7 +101,7 @@ class BatteryService extends Binder {
    private int mBatteryTemperature;
    private String mBatteryTechnology;
    private boolean mBatteryLevelCritical;
    private boolean mInvalidCharger;
    private int mInvalidCharger;

    private int mLastBatteryStatus;
    private int mLastBatteryHealth;
@@ -109,7 +110,7 @@ class BatteryService extends Binder {
    private int mLastBatteryVoltage;
    private int mLastBatteryTemperature;
    private boolean mLastBatteryLevelCritical;
    private boolean mLastInvalidCharger;
    private int mLastInvalidCharger;

    private int mLowBatteryWarningLevel;
    private int mLowBatteryCloseWarningLevel;
@@ -129,6 +130,8 @@ class BatteryService extends Binder {
        mLed = new Led(context, lights);
        mBatteryStats = BatteryStatsService.getService();

        mCriticalBatteryLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
        mLowBatteryWarningLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
@@ -183,7 +186,7 @@ class BatteryService extends Binder {
    private UEventObserver mInvalidChargerObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
            boolean invalidCharger = "1".equals(event.get("SWITCH_STATE"));
            int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;
            if (mInvalidCharger != invalidCharger) {
                mInvalidCharger = invalidCharger;
                update();
@@ -228,11 +231,14 @@ class BatteryService extends Binder {

    private synchronized final void update() {
        native_update();
        processValues();
    }

    private void processValues() {
        boolean logOutlier = false;
        long dischargeDuration = 0;

        mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL;
        mBatteryLevelCritical = mBatteryLevel <= mCriticalBatteryLevel;
        if (mAcOnline) {
            mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
        } else if (mUsbOnline) {
@@ -384,8 +390,8 @@ class BatteryService extends Binder {
        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
        intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);

        if (false) {
            Slog.d(TAG, "updateBattery level:" + mBatteryLevel +
        if (true) {
            Slog.d(TAG, "level:" + mBatteryLevel +
                    " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus +
                    " health:" + mBatteryHealth +  " present:" + mBatteryPresent +
                    " voltage: " + mBatteryVoltage +
@@ -487,6 +493,7 @@ class BatteryService extends Binder {
            return;
        }

        if (args == null || args.length == 0) {
            synchronized (this) {
                pw.println("Current Battery Service state:");
                pw.println("  AC powered: " + mAcOnline);
@@ -500,6 +507,34 @@ class BatteryService extends Binder {
                pw.println("  temperature: " + mBatteryTemperature);
                pw.println("  technology: " + mBatteryTechnology);
            }
        } else if (false) {
            // DO NOT SUBMIT WITH THIS TURNED ON
            if (args.length == 3 && "set".equals(args[0])) {
                String key = args[1];
                String value = args[2];
                try {
                    boolean update = true;
                    if ("ac".equals(key)) {
                        mAcOnline = Integer.parseInt(value) != 0;
                    } else if ("usb".equals(key)) {
                        mUsbOnline = Integer.parseInt(value) != 0;
                    } else if ("status".equals(key)) {
                        mBatteryStatus = Integer.parseInt(value);
                    } else if ("level".equals(key)) {
                        mBatteryLevel = Integer.parseInt(value);
                    } else if ("invalid".equals(key)) {
                        mInvalidCharger = Integer.parseInt(value);
                    } else {
                        update = false;
                    }
                    if (update) {
                        processValues();
                    }
                } catch (NumberFormatException ex) {
                    pw.println("Bad value: " + value);
                }
            }
        }
    }

    class Led {