summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Onorato <joeo@google.com>2010-10-27 15:32:23 -0700
committerJoe Onorato <joeo@google.com>2010-10-27 19:24:51 -0700
commit4ca7f1e2811dc889e526de6c3d30bac8501c23d2 (patch)
tree368ae31cc1b38b912261beebb45181c14dd783e1
parent31b2610dee691f308584dc54b2d936f29f9ca1f7 (diff)
downloadframeworks_base-4ca7f1e2811dc889e526de6c3d30bac8501c23d2.zip
frameworks_base-4ca7f1e2811dc889e526de6c3d30bac8501c23d2.tar.gz
frameworks_base-4ca7f1e2811dc889e526de6c3d30bac8501c23d2.tar.bz2
Implement reminder power dialog and invalid charger dialog.
Bug: 2510318 Bug: 2974431 Change-Id: I92eb419eeffb657e5572a35a490735a96b303d6b
-rw-r--r--core/java/android/os/BatteryManager.java2
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--packages/SystemUI/res/values/strings.xml14
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java226
-rw-r--r--services/java/com/android/server/BatteryService.java73
5 files changed, 235 insertions, 85 deletions
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 247b281..c62715b 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -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}
*/
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c8eb7fd..a6953d4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -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>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1f24ba6..701aa9f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -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. -->
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 0b7b4c0..aeb8d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -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)) {
- showLowBatteryWarning();
- } else if (action.equals(Intent.ACTION_BATTERY_OKAY)
- || action.equals(Intent.ACTION_POWER_CONNECTED)) {
- if (mLowBatteryDialog != null) {
- mLowBatteryDialog.dismiss();
+ 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 {
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);
@@ -98,25 +189,30 @@ public class PowerUI extends SystemUI {
b.setIcon(android.R.drawable.ic_dialog_alert);
b.setPositiveButton(android.R.string.ok, null);
- final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_NO_HISTORY);
- if (intent.resolveActivity(mContext.getPackageManager()) != null) {
- b.setNegativeButton(R.string.battery_low_why,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mContext.startActivity(intent);
- if (mLowBatteryDialog != null) {
- mLowBatteryDialog.dismiss();
- }
+ final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ if (intent.resolveActivity(mContext.getPackageManager()) != null) {
+ b.setNegativeButton(R.string.battery_low_why,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ mContext.startActivity(intent);
+ if (mLowBatteryDialog != null) {
+ mLowBatteryDialog.dismiss();
}
- });
- }
+ }
+ });
+ }
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() {
- public void onDismiss(DialogInterface dialog) {
- mLowBatteryDialog = null;
- mBatteryLevelTextView = null;
+ 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) {
+ 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("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("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));
+ 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)));
}
}
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 23bd5c8..40883bd 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -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,18 +493,47 @@ class BatteryService extends Binder {
return;
}
- synchronized (this) {
- pw.println("Current Battery Service state:");
- pw.println(" AC powered: " + mAcOnline);
- pw.println(" USB powered: " + mUsbOnline);
- pw.println(" status: " + mBatteryStatus);
- pw.println(" health: " + mBatteryHealth);
- pw.println(" present: " + mBatteryPresent);
- pw.println(" level: " + mBatteryLevel);
- pw.println(" scale: " + BATTERY_SCALE);
- pw.println(" voltage:" + mBatteryVoltage);
- pw.println(" temperature: " + mBatteryTemperature);
- pw.println(" technology: " + mBatteryTechnology);
+ if (args == null || args.length == 0) {
+ synchronized (this) {
+ pw.println("Current Battery Service state:");
+ pw.println(" AC powered: " + mAcOnline);
+ pw.println(" USB powered: " + mUsbOnline);
+ pw.println(" status: " + mBatteryStatus);
+ pw.println(" health: " + mBatteryHealth);
+ pw.println(" present: " + mBatteryPresent);
+ pw.println(" level: " + mBatteryLevel);
+ pw.println(" scale: " + BATTERY_SCALE);
+ pw.println(" voltage:" + mBatteryVoltage);
+ 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);
+ }
+ }
}
}