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

Commit 92682905 authored by Joe Onorato's avatar Joe Onorato Committed by Android (Google) Code Review
Browse files

Merge "Implement reminder power dialog and invalid charger dialog."

parents 1e860dfe 4ca7f1e2
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 {