diff options
author | Joe Onorato <joeo@google.com> | 2010-10-27 15:32:23 -0700 |
---|---|---|
committer | Joe Onorato <joeo@google.com> | 2010-10-27 19:24:51 -0700 |
commit | 4ca7f1e2811dc889e526de6c3d30bac8501c23d2 (patch) | |
tree | 368ae31cc1b38b912261beebb45181c14dd783e1 | |
parent | 31b2610dee691f308584dc54b2d936f29f9ca1f7 (diff) | |
download | frameworks_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.java | 2 | ||||
-rw-r--r-- | core/res/res/values/config.xml | 5 | ||||
-rw-r--r-- | packages/SystemUI/res/values/strings.xml | 14 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/power/PowerUI.java | 226 | ||||
-rw-r--r-- | services/java/com/android/server/BatteryService.java | 73 |
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); + } + } } } |