summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jay Wang <jaycwang@google.com> 2024-10-24 06:35:36 +0000
committer Android Build Coastguard Worker <android-build-coastguard-worker@google.com> 2025-04-23 13:37:40 -0700
commit7c7e355d8cfc6586e52dd81709f5fa691c55b791 (patch)
treee0923d9d5139fe996719f86c44d9c82835426984
parentbc763c54a78afbc153af19762a6bd1bf5ec62844 (diff)
Whiskey icon
Bug: 406894719 Test: local test (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e938747540d823eedac92fb6646ee8c3223d7d76) Merged-In: Iead9c06835a227ae870ba71d70a9e9461ef64be9 Change-Id: Iead9c06835a227ae870ba71d70a9e9461ef64be9
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java31
7 files changed, 97 insertions, 7 deletions
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 6a7e048b577a..9fa9605c53b2 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1849,4 +1849,7 @@
<!-- The name of the screen for seeing and installing system updates. [CHAR LIMIT=40]-->
<string name="system_update_settings_list_item_title">System Updates</string>
+
+ <!-- The exclamation symbol defined for the batterymeter. [CHAR LIMIT=NONE]-->
+ <string name="config_batterymeterExclamationPath" translatable="false">M7 12.5h.5V12 6 5.5H7 5 4.5V6v6 .5H5 7ZM4.9064 16.0629l.0147.016.016.0147c.2966.2719.6605.4064 1.0629.4064.4024 0 .7673-.1352 1.0536-.4214.294-.294.4464-.6629.4464-1.0786 0-.4092-.1485-.7731-.4462-1.0538C6.7731 13.6485 6.4092 13.5 6 13.5c-.4157 0-.7846.1525-1.0785.4464L5.275 14.3l-.3536-.3536C4.6352 14.2327 4.5 14.5976 4.5 15c0 .4023.1345.7663.4064 1.0629Z</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 73f6db6d464b..885bf7b4ab93 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -68,6 +68,10 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
private val plusPath = Path()
private val scaledPlus = Path()
+ // Exclamation sign (used for battery alert)
+ private val exclamationPath = Path()
+ private val scaledExclamation = Path()
+
private var intrinsicHeight: Int
private var intrinsicWidth: Int
@@ -106,6 +110,12 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
postInvalidate()
}
+ var alertEnabled = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
private val fillColorStrokePaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p ->
p.color = frameColor
p.alpha = 255
@@ -208,6 +218,12 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
if (!invertFillIcon) {
c.drawPath(scaledBolt, fillPaint)
}
+ } else if (alertEnabled) {
+ // Clip out the exclamation shape
+ unifiedPath.op(scaledExclamation, Path.Op.DIFFERENCE)
+ if (!invertFillIcon) {
+ c.drawPath(scaledExclamation, fillPaint)
+ }
}
if (dualTone) {
@@ -243,6 +259,13 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
} else {
c.drawPath(scaledBolt, fillColorStrokeProtection)
}
+ } else if (alertEnabled) {
+ c.clipOutPath(scaledExclamation)
+ if (invertFillIcon) {
+ c.drawPath(scaledExclamation, fillColorStrokePaint)
+ } else {
+ c.drawPath(scaledExclamation, fillColorStrokeProtection)
+ }
} else if (powerSaveEnabled) {
// If power save is enabled draw the level path with colorError
c.drawPath(levelPath, errorPaint)
@@ -373,6 +396,7 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
scaledFill.computeBounds(fillRect, true)
boltPath.transform(scaleMatrix, scaledBolt)
plusPath.transform(scaleMatrix, scaledPlus)
+ exclamationPath.transform(scaleMatrix, scaledExclamation)
// It is expected that this view only ever scale by the same factor in each dimension, so
// just pick one to scale the strokeWidths
@@ -408,6 +432,10 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int)
com.android.internal.R.string.config_batterymeterPowersavePath)
plusPath.set(PathParser.createPathFromPathData(plusPathString))
+ val exclamationPathString = context.resources.getString(
+ R.string.config_batterymeterExclamationPath)
+ exclamationPath.set(PathParser.createPathFromPathData(exclamationPathString))
+
dualTone = context.resources.getBoolean(
com.android.internal.R.bool.config_batterymeterDualTone)
}
diff --git a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
index b8de117fcbe9..7990c5264a25 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt
@@ -28,7 +28,6 @@ import android.graphics.Rect
import android.graphics.drawable.DrawableWrapper
import android.util.PathParser
import com.android.settingslib.graph.ThemedBatteryDrawable
-import com.android.systemui.res.R
import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT
import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT_WITH_SHIELD
import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH
@@ -36,6 +35,7 @@ import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH_WITH_SHIELD
import com.android.systemui.battery.BatterySpecs.SHIELD_LEFT_OFFSET
import com.android.systemui.battery.BatterySpecs.SHIELD_STROKE
import com.android.systemui.battery.BatterySpecs.SHIELD_TOP_OFFSET
+import com.android.systemui.res.R
/**
* A battery drawable that accessorizes [ThemedBatteryDrawable] with additional information if
@@ -43,10 +43,8 @@ import com.android.systemui.battery.BatterySpecs.SHIELD_TOP_OFFSET
*
* For now, it adds a shield in the bottom-right corner when [displayShield] is true.
*/
-class AccessorizedBatteryDrawable(
- private val context: Context,
- frameColor: Int,
-) : DrawableWrapper(ThemedBatteryDrawable(context, frameColor)) {
+class AccessorizedBatteryDrawable(private val context: Context, frameColor: Int) :
+ DrawableWrapper(ThemedBatteryDrawable(context, frameColor)) {
private val mainBatteryDrawable: ThemedBatteryDrawable
get() = drawable as ThemedBatteryDrawable
@@ -105,7 +103,7 @@ class AccessorizedBatteryDrawable(
b.left,
b.top,
/* right= */ b.left + mainWidth.toInt(),
- /* bottom= */ b.top + mainHeight.toInt()
+ /* bottom= */ b.top + mainHeight.toInt(),
)
if (displayShield) {
@@ -198,6 +196,16 @@ class AccessorizedBatteryDrawable(
return mainBatteryDrawable.powerSaveEnabled
}
+ /** Sets whether battery alert is enabled. */
+ fun setAlertEnabled(alertEnabled: Boolean) {
+ mainBatteryDrawable.alertEnabled = alertEnabled
+ }
+
+ /** Returns whether battery alert is currently enabled. */
+ fun getAlertEnabled(): Boolean {
+ return mainBatteryDrawable.alertEnabled
+ }
+
/** Sets the colors to use for the icon. */
fun setColors(fgColor: Int, bgColor: Int, singleToneColor: Int) {
shieldPaint.color = if (dualTone) fgColor else singleToneColor
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index e63472684585..ddebd21b1800 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -90,6 +90,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
private boolean mIsIncompatibleCharging;
// Error state where we know nothing about the current battery state
private boolean mBatteryStateUnknown;
+ private boolean mBatteryStateAlert;
// Lazily-loaded since this is expected to be a rare-if-ever state
private Drawable mUnknownStateDrawable;
@@ -610,6 +611,17 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
updateShowPercent();
}
+ void onBatteryAlertStateChanged(boolean isAlert) {
+ if (mBatteryStateAlert == isAlert) {
+ return;
+ }
+
+ mBatteryStateAlert = isAlert;
+ if (!newStatusBarIcons()) {
+ mDrawable.setAlertEnabled(isAlert);
+ }
+ }
+
void scaleBatteryMeterViews() {
if (!newStatusBarIcons()) {
scaleBatteryMeterViewsLegacy();
@@ -775,6 +787,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
pw.println(" mBatteryStateUnknown: " + mBatteryStateUnknown);
pw.println(" mIsIncompatibleCharging: " + mIsIncompatibleCharging);
pw.println(" mPluggedIn: " + mPluggedIn);
+ pw.println(" mBatteryStateAlert: " + mBatteryStateAlert);
pw.println(" mLevel: " + mLevel);
pw.println(" mMode: " + mShowPercentMode);
if (newStatusBarIcons()) {
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
index fcf51051940c..655f584554b5 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
@@ -117,6 +117,11 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView>
pw.println(" location=" + mLocation);
mView.dump(pw, args);
}
+
+ @Override
+ public void onBatteryAlertStateChanged(boolean isAlert) {
+ mView.onBatteryAlertStateChanged(isAlert);
+ }
};
private final UserTracker.Callback mUserChangedCallback =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 92731037dc64..7edb73777714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -165,6 +165,10 @@ public interface BatteryController extends DemoMode,
default void onIsIncompatibleChargingChanged(boolean isIncompatibleCharging) {
}
+ /** Calls when the battery is in an alert state. */
+ default void onBatteryAlertStateChanged(boolean isAlert) {
+ }
+
@Override
default void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index d281920ab1c4..2d7830ab3417 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -19,6 +19,9 @@ package com.android.systemui.statusbar.policy;
import static android.os.BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
+import static android.os.BatteryManager.BATTERY_HEALTH_DEAD;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_HEALTH;
import static android.os.BatteryManager.EXTRA_PRESENT;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
@@ -94,6 +97,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private int mPluggedChargingSource;
protected boolean mCharging;
private boolean mStateUnknown = false;
+ private boolean mStateAlert = false;
private boolean mCharged;
protected boolean mPowerSave;
private boolean mAodPowerSave;
@@ -192,6 +196,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
ipw.println(mPowerSave);
ipw.print("mStateUnknown=");
ipw.println(mStateUnknown);
+ ipw.print("mStateAlert=");
+ ipw.println(mStateAlert);
ipw.println("Callbacks:------------------");
// Since the above lines are already indented, we need to indent twice for the callbacks.
ipw.increaseIndent();
@@ -236,6 +242,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
cb.onWirelessChargingChanged(mWirelessCharging);
cb.onIsBatteryDefenderChanged(mIsBatteryDefender);
cb.onIsIncompatibleChargingChanged(mIsIncompatibleCharging);
+ cb.onBatteryAlertStateChanged(mStateAlert);
}
@Override
@@ -289,6 +296,14 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
if (mPluggedChargingSource != previousPluggedChargingSource) {
updatePowerSave();
}
+
+ int batteryHealth = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+ boolean isAlert = batteryHealth == BATTERY_HEALTH_DEAD;
+ if (isAlert != mStateAlert) {
+ mStateAlert = isAlert;
+ fireBatteryAlertStateChanged();
+ }
+
fireBatteryLevelChanged();
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
updatePowerSave();
@@ -510,6 +525,15 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
(callback) -> callback.onIsIncompatibleChargingChanged(mIsIncompatibleCharging));
}
+ private void fireBatteryAlertStateChanged() {
+ synchronized (mChangeCallbacks) {
+ final int n = mChangeCallbacks.size();
+ for (int i = 0; i < n; i++) {
+ mChangeCallbacks.get(i).onBatteryAlertStateChanged(mStateAlert);
+ }
+ }
+ }
+
@Override
public void dispatchDemoCommand(String command, Bundle args) {
if (!mDemoModeController.isInDemoMode()) {
@@ -522,6 +546,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
String present = args.getString("present");
String defender = args.getString("defender");
String incompatible = args.getString("incompatible");
+ String alert = args.getString("alert");
if (level != null) {
mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
}
@@ -544,6 +569,10 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mIsIncompatibleCharging = incompatible.equals("true");
fireIsIncompatibleChargingChanged();
}
+ if (alert != null) {
+ mStateAlert = alert.equals("true");
+ fireBatteryAlertStateChanged();
+ }
fireBatteryLevelChanged();
}
@@ -569,4 +598,4 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
public boolean isChargingSourceDock() {
return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_DOCK;
}
-} \ No newline at end of file
+}