Merge "Update low battery notification mechanism" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-03-01 03:54:30 +00:00
committed by Android (Google) Code Review
6 changed files with 49 additions and 41 deletions

View File

@@ -1207,13 +1207,13 @@
<!-- Display low battery warning when battery level dips to this value. <!-- Display low battery warning when battery level dips to this value.
Also, the battery stats are flushed to disk when we hit this level. --> Also, the battery stats are flushed to disk when we hit this level. -->
<integer name="config_criticalBatteryWarningLevel">5</integer> <integer name="config_criticalBatteryWarningLevel">10</integer>
<!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. --> <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
<integer name="config_shutdownBatteryTemperature">680</integer> <integer name="config_shutdownBatteryTemperature">680</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> <integer name="config_lowBatteryWarningLevel">20</integer>
<!-- The default suggested battery % at which we enable battery saver automatically. --> <!-- The default suggested battery % at which we enable battery saver automatically. -->
<integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer> <integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer>

View File

@@ -487,6 +487,9 @@
space --> space -->
<bool name="config_showBatteryEstimateQSBH">false</bool> <bool name="config_showBatteryEstimateQSBH">false</bool>
<!-- Whether to show a severe low battery dialog. -->
<bool name="config_severe_battery_dialog">false</bool>
<!-- A path similar to frameworks/base/core/res/res/values/config.xml <!-- A path similar to frameworks/base/core/res/res/values/config.xml
config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display
cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then

View File

@@ -21,7 +21,13 @@
<string name="app_label">System UI</string> <string name="app_label">System UI</string>
<!-- When the battery is low, this is displayed to the user in a dialog. The title of the low battery alert. [CHAR LIMIT=NONE]--> <!-- When the battery is low, this is displayed to the user in a dialog. The title of the low battery alert. [CHAR LIMIT=NONE]-->
<string name="battery_low_title">Battery may run out soon</string> <string name="battery_low_title">Turn on Battery Saver?</string>
<!-- When the battery is low, this is displayed to the user in a dialog. The description of the low battery alert. [CHAR LIMIT=NONE]-->
<string name="battery_low_description">You have <xliff:g id="percentage" example="20%">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity, and delays notifications.</string>
<!-- When the battery is low at first time, this is displayed to the user in a dialog. The description of the low battery alert. [CHAR LIMIT=NONE]-->
<string name="battery_low_intro">Battery Saver turns on Dark theme, restricts background activity, and delays notifications.</string>
<!-- A message that appears when the battery level is getting low in a dialog. This is <!-- A message that appears when the battery level is getting low in a dialog. This is
appended to the subtitle of the low battery alert. "percentage" is the percentage of battery appended to the subtitle of the low battery alert. "percentage" is the percentage of battery

View File

@@ -118,6 +118,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private static final String ACTION_AUTO_SAVER_NO_THANKS = private static final String ACTION_AUTO_SAVER_NO_THANKS =
"PNW.autoSaverNoThanks"; "PNW.autoSaverNoThanks";
private static final String ACTION_ENABLE_SEVERE_BATTERY_DIALOG = "PNW.enableSevereDialog";
private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING = private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
"android.settings.BATTERY_SAVER_SETTINGS"; "android.settings.BATTERY_SAVER_SETTINGS";
public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION = public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION =
@@ -253,20 +255,25 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
} }
protected void showWarningNotification() { protected void showWarningNotification() {
final String percentage = NumberFormat.getPercentInstance() if (showSevereLowBatteryDialog()) {
.format((double) mCurrentBatterySnapshot.getBatteryLevel() / 100.0); mContext.sendBroadcast(new Intent(ACTION_ENABLE_SEVERE_BATTERY_DIALOG)
.setPackage(mContext.getPackageName())
// get shared standard notification copy .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
String title = mContext.getString(R.string.battery_low_title); | Intent.FLAG_RECEIVER_FOREGROUND));
String contentText; // Reset the state once dialog been enabled
dismissLowBatteryNotification();
// get correct content text if notification is hybrid or not mPlaySound = false;
if (mCurrentBatterySnapshot.isHybrid()) { return;
contentText = getHybridContentString(percentage);
} else {
contentText = mContext.getString(R.string.battery_low_percent_format, percentage);
} }
final int warningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
final String percentage = NumberFormat.getPercentInstance()
.format((double) warningLevel / 100.0);
final String title = mContext.getString(R.string.battery_low_title);
final String contentText = mContext.getString(
R.string.battery_low_description, percentage);
final Notification.Builder nb = final Notification.Builder nb =
new Notification.Builder(mContext, NotificationChannels.BATTERY) new Notification.Builder(mContext, NotificationChannels.BATTERY)
.setSmallIcon(R.drawable.ic_power_low) .setSmallIcon(R.drawable.ic_power_low)
@@ -284,7 +291,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
} }
// Make the notification red if the percentage goes below a certain amount or the time // Make the notification red if the percentage goes below a certain amount or the time
// remaining estimate is disabled // remaining estimate is disabled
if (!mCurrentBatterySnapshot.isHybrid() || mBucket < 0 if (!mCurrentBatterySnapshot.isHybrid() || mBucket < -1
|| mCurrentBatterySnapshot.getTimeRemainingMillis() || mCurrentBatterySnapshot.getTimeRemainingMillis()
< mCurrentBatterySnapshot.getSevereThresholdMillis()) { < mCurrentBatterySnapshot.getSevereThresholdMillis()) {
nb.setColor(Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError)); nb.setColor(Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError));
@@ -303,6 +310,13 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL); mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL);
} }
private boolean showSevereLowBatteryDialog() {
final boolean isSevereState = !mCurrentBatterySnapshot.isHybrid() || mBucket < -1;
final boolean useSevereDialog = mContext.getResources().getBoolean(
R.bool.config_severe_battery_dialog);
return isSevereState && useSevereDialog;
}
private void showAutoSaverSuggestionNotification() { private void showAutoSaverSuggestionNotification() {
final CharSequence message = mContext.getString(R.string.auto_saver_text); final CharSequence message = mContext.getString(R.string.auto_saver_text);
final Notification.Builder nb = final Notification.Builder nb =
@@ -662,8 +676,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
// If there's no link, use the string with no "learn more". // If there's no link, use the string with no "learn more".
if (TextUtils.isEmpty(learnMoreUrl)) { if (TextUtils.isEmpty(learnMoreUrl)) {
return mContext.getText( return mContext.getText(R.string.battery_low_intro);
com.android.internal.R.string.battery_saver_description);
} }
// If we have a link, use the string with the "learn more" link. // If we have a link, use the string with the "learn more" link.

View File

@@ -69,7 +69,7 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS; private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS;
private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
static final long THREE_HOURS_IN_MILLIS = DateUtils.HOUR_IN_MILLIS * 3; static final long THREE_HOURS_IN_MILLIS = DateUtils.HOUR_IN_MILLIS * 3;
private static final int CHARGE_CYCLE_PERCENT_RESET = 45; private static final int CHARGE_CYCLE_PERCENT_RESET = 30;
private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis(); private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis();
public static final int NO_ESTIMATE_AVAILABLE = -1; public static final int NO_ESTIMATE_AVAILABLE = -1;
private static final String BOOT_COUNT_KEY = "boot_count"; private static final String BOOT_COUNT_KEY = "boot_count";
@@ -206,7 +206,8 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
* *
* 1 means that the battery is "ok" * 1 means that the battery is "ok"
* 0 means that the battery is between "ok" and what we should warn about. * 0 means that the battery is between "ok" and what we should warn about.
* less than 0 means that the battery is low * less than 0 means that the battery is low, -1 means the battery is reaching warning level,
* -2 means the battery is reaching severe level.
*/ */
private int findBatteryLevelBucket(int level) { private int findBatteryLevelBucket(int level) {
if (level >= mLowBatteryAlertCloseLevel) { if (level >= mLowBatteryAlertCloseLevel) {
@@ -388,12 +389,8 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
@VisibleForTesting @VisibleForTesting
void maybeShowHybridWarning(BatteryStateSnapshot currentSnapshot, void maybeShowHybridWarning(BatteryStateSnapshot currentSnapshot,
BatteryStateSnapshot lastSnapshot) { BatteryStateSnapshot lastSnapshot) {
// if we are now over 45% battery & 6 hours remaining so we can trigger hybrid // if we are now over 30% battery, we can trigger hybrid notification again
// notification again if (currentSnapshot.getBatteryLevel() >= CHARGE_CYCLE_PERCENT_RESET) {
final long timeRemainingMillis = currentSnapshot.getTimeRemainingMillis();
if (currentSnapshot.getBatteryLevel() >= CHARGE_CYCLE_PERCENT_RESET
&& (timeRemainingMillis > SIX_HOURS_MILLIS
|| timeRemainingMillis == NO_ESTIMATE_AVAILABLE)) {
mLowWarningShownThisChargeCycle = false; mLowWarningShownThisChargeCycle = false;
mSevereWarningShownThisChargeCycle = false; mSevereWarningShownThisChargeCycle = false;
if (DEBUG) { if (DEBUG) {
@@ -403,6 +400,7 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket() final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket()
|| lastSnapshot.getPlugged(); || lastSnapshot.getPlugged();
final long timeRemainingMillis = currentSnapshot.getTimeRemainingMillis();
if (shouldShowHybridWarning(currentSnapshot)) { if (shouldShowHybridWarning(currentSnapshot)) {
mWarnings.showLowBatteryWarning(playSound); mWarnings.showLowBatteryWarning(playSound);
@@ -444,19 +442,13 @@ public class PowerUI extends CoreStartable implements CommandQueue.Callbacks {
return false; return false;
} }
final long timeRemainingMillis = snapshot.getTimeRemainingMillis();
// Only show the low warning if enabled once per charge cycle & no battery saver // Only show the low warning if enabled once per charge cycle & no battery saver
final boolean canShowWarning = snapshot.isLowWarningEnabled() final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
&& !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver() && snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold();
&& ((timeRemainingMillis != NO_ESTIMATE_AVAILABLE
&& timeRemainingMillis < snapshot.getLowThresholdMillis())
|| snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold());
// Only show the severe warning once per charge cycle // Only show the severe warning once per charge cycle
final boolean canShowSevereWarning = !mSevereWarningShownThisChargeCycle final boolean canShowSevereWarning = !mSevereWarningShownThisChargeCycle
&& ((timeRemainingMillis != NO_ESTIMATE_AVAILABLE && snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold();
&& timeRemainingMillis < snapshot.getSevereThresholdMillis())
|| snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold());
final boolean canShow = canShowWarning || canShowSevereWarning; final boolean canShow = canShowWarning || canShowSevereWarning;

View File

@@ -430,12 +430,6 @@ public class PowerUITest extends SysuiTestCase {
state.mIsPowerSaver = true; state.mIsPowerSaver = true;
shouldShow = mPowerUI.shouldShowHybridWarning(state.get()); shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
assertThat(shouldShow).isFalse(); assertThat(shouldShow).isFalse();
state.mIsPowerSaver = false;
// if disabled we should not show the low warning.
state.mIsLowLevelWarningEnabled = false;
shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
assertThat(shouldShow).isFalse();
} }
@Test @Test