Create a battery icon that loads paths
Create a new battery drawable that will load enough resources from
frameworks/base/core/res/res/ to allow for theming overlays. The current
things are overlayable:
- Perimeter path: the outer shape of the battery (including the
terminal)
- Fill mask: path defining the shape of the fill
- Bolt path: charging bolt path. draws with appropriate protection for
visibilty
- Powersave path: path of the plus sign that draws when in powersave
mode. also draws with protection
Test: visual; sysui demo mode
Bug: 123705805
Change-Id: I2bb15fd10e3fec63cb115a8f216794933b717404
diff --git a/core/res/res/drawable/ic_qs_battery_saver.xml b/core/res/res/drawable/ic_qs_battery_saver.xml
index 89b2569..93975b6 100644
--- a/core/res/res/drawable/ic_qs_battery_saver.xml
+++ b/core/res/res/drawable/ic_qs_battery_saver.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2018 The Android Open Source Project
+ Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,8 +21,10 @@
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
- android:pathData="M5,3
- l3.5,0 l0,-1.5 l7,0 l0,1.5 l3.5,0 l0,19.5 l-14,0z
- M10.5,8.5 l0,3 l-3,0 l0,3 l3,0 l0,3 l3,0 l0,-3 l3,0 l0,-3 l-3,0 l0,-3 z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FFF"
+ android:pathData="M16.67,4H14.5V2h-5v2H7.33C6.6,4 6,4.6 6,5.33V15v5.67C6,21.4 6.6,22 7.33,22h9.33C17.4,22 18,21.4 18,20.67V15V5.33C18,4.6 17.4,4 16.67,4zM16,15v5H8v-5V6h8V15z"/>
+ <path
+ android:fillColor="#FFF"
+ android:pathData="M15,12l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z"/>
+
</vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6e2b77f..d76beb5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3926,4 +3926,25 @@
The same restrictions apply to this array. -->
<array name="config_displayWhiteBalanceDisplayColorTemperatures">
</array>
+
+ <!-- All of the paths defined for the batterymeter are defined on a 12x20 canvas, and must
+ be parsable by android.utill.PathParser -->
+ <string name="config_batterymeterPerimeterPath" translatable="false">
+ M3.5,2 v0 H1.33 C0.6,2 0,2.6 0,3.33 V13v5.67 C0,19.4 0.6,20 1.33,20 h9.33 C11.4,20 12,19.4 12,18.67 V13V3.33 C12,2.6 11.4,2 10.67,2 H8.5 V0 H3.5 z M2,18v-7V4h8v9v5H2L2,18z
+ </string>
+
+ <string name="config_batterymeterFillMask" translatable="false">
+ M2,18 v-14 h8 v14 z
+ </string>
+ <string name="config_batterymeterBoltPath" translatable="false">
+ M5,17.5 V12 H3 L7,4.5 V10 h2 L5,17.5 z
+ </string>
+ <string name="config_batterymeterPowersavePath" translatable="false">
+ M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z
+ </string>
+
+ <!-- A dual tone battery meter draws the perimeter path twice - once to define the shape
+ and a second time clipped to the fill level to indicate charge -->
+ <bool name="config_batterymeterDualTone">false</bool>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 16aed90..e8e86fd 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3193,6 +3193,11 @@
<java-symbol type="raw" name="fallback_categories" />
<java-symbol type="string" name="config_icon_mask" />
+ <java-symbol type="string" name="config_batterymeterPerimeterPath" />
+ <java-symbol type="string" name="config_batterymeterFillMask" />
+ <java-symbol type="string" name="config_batterymeterBoltPath" />
+ <java-symbol type="string" name="config_batterymeterPowersavePath" />
+ <java-symbol type="bool" name="config_batterymeterDualTone" />
<!-- Accessibility Shortcut -->
<java-symbol type="string" name="accessibility_shortcut_warning_dialog_title" />
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index caa928f..730e9e1 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -29,7 +29,7 @@
resource_dirs: ["res"],
- srcs: ["src/**/*.java"],
+ srcs: ["src/**/*.java", "src/**/*.kt"],
min_sdk_version: "21",
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
new file mode 100644
index 0000000..337106b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settingslib.graph
+
+import android.content.Context
+import android.graphics.BlendMode
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.ColorFilter
+import android.graphics.Matrix
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PixelFormat
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.util.PathParser
+import android.util.TypedValue
+
+import com.android.settingslib.R
+import com.android.settingslib.Utils
+
+/**
+ * A battery meter drawable that respects paths configured in
+ * frameworks/base/core/res/res/values/config.xml to allow for an easily overrideable battery icon
+ */
+open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) : Drawable() {
+
+ // Need to load:
+ // 1. perimeter shape
+ // 2. fill mask (if smaller than perimeter, this would create a fill that
+ // doesn't touch the walls
+ private val perimeterPath = Path()
+ private val scaledPerimeter = Path()
+ // Fill will cover the whole bounding rect of the fillMask, and be masked by the path
+ private val fillMask = Path()
+ private val scaledFill = Path()
+ // Based off of the mask, the fill will interpolate across this space
+ private val fillRect = RectF()
+ // Top of this rect changes based on level, 100% == fillRect
+ private val levelRect = RectF()
+ private val levelPath = Path()
+ // Updates the transform of the paths when our bounds change
+ private val scaleMatrix = Matrix()
+ private val padding = Rect()
+ // The net result of fill + perimeter paths
+ private val unifiedPath = Path()
+
+ // Bolt path (used while charging)
+ private val boltPath = Path()
+ private val scaledBolt = Path()
+
+ // Plus sign (used for power save mode)
+ private val plusPath = Path()
+ private val scaledPlus = Path()
+
+ private var intrinsicHeight: Int
+ private var intrinsicWidth: Int
+
+ // To implement hysteresis, keep track of the need to invert the interior icon of the battery
+ private var invertFillIcon = false
+
+ // Colors can be configured based on battery level (see res/values/arrays.xml)
+ private var colorLevels: IntArray
+
+ private var fillColor: Int = Color.MAGENTA
+ private var backgroundColor: Int = Color.MAGENTA
+ // updated whenever level changes
+ private var levelColor: Int = Color.MAGENTA
+
+ // Dual tone implies that battery level is a clipped overlay over top of the whole shape
+ private var dualTone = false
+
+ private val invalidateRunnable: () -> Unit = {
+ invalidateSelf()
+ }
+
+ open var criticalLevel: Int = 0
+
+ var charging = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ var powerSaveEnabled = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ private val fillColorStrokePaint: Paint by lazy {
+ val p = Paint(Paint.ANTI_ALIAS_FLAG)
+ p.color = frameColor
+ p.isDither = true
+ p.strokeWidth = 5f
+ p.style = Paint.Style.STROKE
+ p.blendMode = BlendMode.SRC
+ p.strokeMiter = 5f
+ p
+ }
+
+ private val fillColorStrokeProtection: Paint by lazy {
+ val p = Paint(Paint.ANTI_ALIAS_FLAG)
+ p.isDither = true
+ p.strokeWidth = 5f
+ p.style = Paint.Style.STROKE
+ p.blendMode = BlendMode.CLEAR
+ p.strokeMiter = 5f
+ p
+ }
+
+ private val fillPaint: Paint by lazy {
+ val p = Paint(Paint.ANTI_ALIAS_FLAG)
+ p.color = frameColor
+ p.alpha = 255
+ p.isDither = true
+ p.strokeWidth = 0f
+ p.style = Paint.Style.FILL_AND_STROKE
+ p
+ }
+
+ // Only used if dualTone is set to true
+ private val dualToneBackgroundFill: Paint by lazy {
+ val p = Paint(Paint.ANTI_ALIAS_FLAG)
+ p.color = frameColor
+ p.alpha = 255
+ p.isDither = true
+ p.strokeWidth = 0f
+ p.style = Paint.Style.FILL_AND_STROKE
+ p
+ }
+
+ init {
+ val density = context.resources.displayMetrics.density
+ intrinsicHeight = (Companion.HEIGHT * density).toInt()
+ intrinsicWidth = (Companion.WIDTH * density).toInt()
+
+ val res = context.resources
+ val levels = res.obtainTypedArray(R.array.batterymeter_color_levels)
+ val colors = res.obtainTypedArray(R.array.batterymeter_color_values)
+ val N = levels.length()
+ colorLevels = IntArray(2 * N)
+ for (i in 0 until N) {
+ colorLevels[2 * i] = levels.getInt(i, 0)
+ if (colors.getType(i) == TypedValue.TYPE_ATTRIBUTE) {
+ colorLevels[2 * i + 1] = Utils.getColorAttrDefaultColor(context,
+ colors.getThemeAttributeId(i, 0))
+ } else {
+ colorLevels[2 * i + 1] = colors.getColor(i, 0)
+ }
+ }
+ levels.recycle()
+ colors.recycle()
+
+ criticalLevel = context.resources.getInteger(
+ com.android.internal.R.integer.config_criticalBatteryWarningLevel)
+
+ loadPaths()
+ }
+
+ override fun draw(c: Canvas) {
+ unifiedPath.reset()
+ levelPath.reset()
+ levelRect.set(fillRect)
+ val fillFraction = level / 100f
+ val fillTop =
+ if (level >= 95)
+ fillRect.top
+ else
+ fillRect.top + (fillRect.height() * (1 - fillFraction))
+
+ levelRect.top = Math.floor(fillTop.toDouble()).toFloat()
+ levelPath.addRect(levelRect, Path.Direction.CCW)
+
+ // The perimeter should never change
+ unifiedPath.addPath(scaledPerimeter)
+ // IF drawing dual tone, the level is used only to clip the whole drawable path
+ if (!dualTone) {
+ unifiedPath.op(levelPath, Path.Op.UNION)
+ }
+
+ fillPaint.color = levelColor
+
+ // Deal with unifiedPath clipping before it draws
+ if (charging) {
+ // Clip out the bolt shape
+ unifiedPath.op(scaledBolt, Path.Op.DIFFERENCE)
+ if (!invertFillIcon) {
+ c.drawPath(scaledBolt, fillPaint)
+ }
+ } else if (powerSaveEnabled) {
+ // Clip out the plus shape
+ unifiedPath.op(scaledPlus, Path.Op.DIFFERENCE)
+ if (!invertFillIcon) {
+ c.drawPath(scaledPlus, fillPaint)
+ }
+ }
+
+ if (dualTone) {
+ // Dual tone means we draw the shape again, clipped to the charge level
+ c.drawPath(unifiedPath, dualToneBackgroundFill)
+ c.save()
+ c.clipRect(0f,
+ bounds.bottom - bounds.height() * fillFraction,
+ bounds.right.toFloat(),
+ bounds.bottom.toFloat())
+ c.drawPath(unifiedPath, fillPaint)
+ c.restore()
+ } else {
+ // Non dual-tone means we draw the perimeter (with the level fill), and potentially
+ // draw the fill again with a critical color
+ fillPaint.color = fillColor
+ c.drawPath(unifiedPath, fillPaint)
+ fillPaint.color = levelColor
+
+ // Show colorError below this level
+ if (level <= Companion.CRITICAL_LEVEL && !charging) {
+ c.save()
+ c.clipPath(scaledFill)
+ c.drawPath(levelPath, fillPaint)
+ c.restore()
+ }
+ }
+
+ if (charging) {
+ c.clipOutPath(scaledBolt)
+ if (invertFillIcon) {
+ c.drawPath(scaledBolt, fillColorStrokePaint)
+ } else {
+ c.drawPath(scaledBolt, fillColorStrokeProtection)
+ }
+ } else if (powerSaveEnabled) {
+ c.clipOutPath(scaledPlus)
+ if (invertFillIcon) {
+ c.drawPath(scaledPlus, fillColorStrokePaint)
+ } else {
+ c.drawPath(scaledPlus, fillColorStrokeProtection)
+ }
+ }
+ }
+
+ private fun batteryColorForLevel(level: Int): Int {
+ return when {
+ charging || powerSaveEnabled -> fillPaint.color
+ else -> getColorForLevel(level)
+ }
+ }
+
+ private fun getColorForLevel(level: Int): Int {
+ var thresh: Int
+ var color = 0
+ var i = 0
+ while (i < colorLevels.size) {
+ thresh = colorLevels[i]
+ color = colorLevels[i + 1]
+ if (level <= thresh) {
+
+ // Respect tinting for "normal" level
+ return if (i == colorLevels.size - 2) {
+ fillColor
+ } else {
+ color
+ }
+ }
+ i += 2
+ }
+ return color
+ }
+
+ /**
+ * Alpha is unused internally, and should be defined in the colors passed to {@link setColors}.
+ * Further, setting an alpha for a dual tone battery meter doesn't make sense without bounds
+ * defining the minimum background fill alpha. This is because fill + background must be equal
+ * to the net alpha passed in here.
+ */
+ override fun setAlpha(alpha: Int) {
+ }
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ fillPaint.colorFilter = colorFilter
+ fillColorStrokePaint.colorFilter = colorFilter
+ dualToneBackgroundFill.colorFilter = colorFilter
+ }
+
+ /**
+ * Deprecated, but required by Drawable
+ */
+ override fun getOpacity(): Int {
+ return PixelFormat.OPAQUE
+ }
+
+ override fun getIntrinsicHeight(): Int {
+ return intrinsicHeight
+ }
+
+ override fun getIntrinsicWidth(): Int {
+ return intrinsicWidth
+ }
+
+ /**
+ * Set the fill level
+ */
+ public open fun setBatteryLevel(l: Int) {
+ invertFillIcon = if (l >= 67) true else if (l <= 33) false else invertFillIcon
+ level = l
+ levelColor = batteryColorForLevel(level)
+ invalidateSelf()
+ }
+
+ public fun getBatteryLevel(): Int {
+ return level
+ }
+
+ override fun onBoundsChange(bounds: Rect?) {
+ super.onBoundsChange(bounds)
+ updateSize()
+ }
+
+ fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
+ padding.left = left
+ padding.top = top
+ padding.right = right
+ padding.bottom = bottom
+
+ updateSize()
+ }
+
+ fun setColors(fgColor: Int, bgColor: Int, singleToneColor: Int) {
+ fillColor = if (dualTone) fgColor else singleToneColor
+
+ fillPaint.color = fillColor
+ fillColorStrokePaint.color = fillColor
+
+ backgroundColor = bgColor
+ dualToneBackgroundFill.color = bgColor
+
+ invalidateSelf()
+ }
+
+ private fun postInvalidate() {
+ unscheduleSelf(invalidateRunnable)
+ scheduleSelf(invalidateRunnable, 0)
+ }
+
+ private fun updateSize() {
+ val b = bounds
+ if (b.isEmpty) {
+ scaleMatrix.setScale(1f, 1f)
+ } else {
+ scaleMatrix.setScale((b.right / Companion.WIDTH), (b.bottom / Companion.HEIGHT))
+ }
+
+ perimeterPath.transform(scaleMatrix, scaledPerimeter)
+ fillMask.transform(scaleMatrix, scaledFill)
+ scaledFill.computeBounds(fillRect, true)
+ boltPath.transform(scaleMatrix, scaledBolt)
+ plusPath.transform(scaleMatrix, scaledPlus)
+ }
+
+ private fun loadPaths() {
+ val pathString = context.resources.getString(
+ com.android.internal.R.string.config_batterymeterPerimeterPath)
+ perimeterPath.set(PathParser.createPathFromPathData(pathString))
+ val b = RectF()
+ perimeterPath.computeBounds(b, true)
+
+ val fillMaskString = context.resources.getString(
+ com.android.internal.R.string.config_batterymeterFillMask)
+ fillMask.set(PathParser.createPathFromPathData(fillMaskString))
+ // Set the fill rect so we can calculate the fill properly
+ fillMask.computeBounds(fillRect, true)
+
+ val boltPathString = context.resources.getString(
+ com.android.internal.R.string.config_batterymeterBoltPath)
+ boltPath.set(PathParser.createPathFromPathData(boltPathString))
+
+ val plusPathString = context.resources.getString(
+ com.android.internal.R.string.config_batterymeterPowersavePath)
+ plusPath.set(PathParser.createPathFromPathData(plusPathString))
+
+ dualTone = context.resources.getBoolean(
+ com.android.internal.R.bool.config_batterymeterDualTone)
+ }
+
+ companion object {
+ private const val TAG = "ThemedBatteryDrawable"
+ private const val WIDTH = 12f
+ private const val HEIGHT = 20f
+ private const val CRITICAL_LEVEL = 15
+ }
+}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1e1245f..fd5a362 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -39,8 +39,9 @@
<!-- Height of the battery icon in the status bar. -->
<dimen name="status_bar_battery_icon_height">13.0dp</dimen>
- <!-- Width of the battery icon in the status bar. -->
- <dimen name="status_bar_battery_icon_width">8.5dp</dimen>
+ <!-- Width of the battery icon in the status bar. The battery drawable assumes a 12x20 canvas,
+ so the width of the icon should be 13.0dp * (12.0 / 20.0) -->
+ <dimen name="status_bar_battery_icon_width">7.8dp</dimen>
<!-- The font size for the clock in the status bar. -->
<dimen name="status_bar_clock_size">14sp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 2006794..592b603 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -46,7 +46,7 @@
import android.widget.TextView;
import com.android.settingslib.Utils;
-import com.android.settingslib.graph.BatteryMeterDrawableBase;
+import com.android.settingslib.graph.ThemedBatteryDrawable;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.settings.CurrentUserTracker;
@@ -76,7 +76,7 @@
public static final int MODE_OFF = 2;
public static final int MODE_ESTIMATE = 3;
- private final BatteryMeterDrawableBase mDrawable;
+ private final ThemedBatteryDrawable mDrawable;
private final String mSlotBattery;
private final ImageView mBatteryIconView;
private final CurrentUserTracker mUserTracker;
@@ -94,9 +94,11 @@
private boolean mIsSubscribedForTunerUpdates;
private boolean mCharging;
+ private int mDarkModeSingleToneColor;
private int mDarkModeBackgroundColor;
private int mDarkModeFillColor;
+ private int mLightModeSingleToneColor;
private int mLightModeBackgroundColor;
private int mLightModeFillColor;
private int mUser;
@@ -106,6 +108,7 @@
*/
private boolean mUseWallpaperTextColors;
+ private int mNonAdaptedSingleToneColor;
private int mNonAdaptedForegroundColor;
private int mNonAdaptedBackgroundColor;
@@ -127,7 +130,7 @@
defStyle, 0);
final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
context.getColor(R.color.meter_background_color));
- mDrawable = new BatteryMeterDrawableBase(context, frameColor);
+ mDrawable = new ThemedBatteryDrawable(context, frameColor);
atts.recycle();
mSettingObserver = new SettingObserver(new Handler(context.getMainLooper()));
@@ -169,6 +172,10 @@
setClipChildren(false);
setClipToPadding(false);
Dependency.get(ConfigurationController.class).observe(viewAttachLifecycle(this), this);
+
+ // Needed for PorderDuff.Mode.CLEAR operations to work properly, but redraws don't happen
+ // enough to justify a hardware layer.
+ setLayerType(LAYER_TYPE_SOFTWARE, null);
}
public void setForceShowPercent(boolean show) {
@@ -243,9 +250,11 @@
if (mUseWallpaperTextColors) {
updateColors(
Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor),
- Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColorSecondary));
+ Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColorSecondary),
+ Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor));
} else {
- updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor);
+ updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor,
+ mNonAdaptedSingleToneColor);
}
}
@@ -258,10 +267,14 @@
Utils.getThemeAttr(context, R.attr.darkIconTheme));
Context dualToneLightTheme = new ContextThemeWrapper(context,
Utils.getThemeAttr(context, R.attr.lightIconTheme));
+ mDarkModeSingleToneColor = Utils.getColorAttrDefaultColor(dualToneDarkTheme,
+ R.attr.singleToneColor);
mDarkModeBackgroundColor = Utils.getColorAttrDefaultColor(dualToneDarkTheme,
R.attr.backgroundColor);
mDarkModeFillColor = Utils.getColorAttrDefaultColor(dualToneDarkTheme,
R.attr.fillColor);
+ mLightModeSingleToneColor = Utils.getColorAttrDefaultColor(dualToneLightTheme,
+ R.attr.singleToneColor);
mLightModeBackgroundColor = Utils.getColorAttrDefaultColor(dualToneLightTheme,
R.attr.backgroundColor);
mLightModeFillColor = Utils.getColorAttrDefaultColor(dualToneLightTheme, R.attr.fillColor);
@@ -303,8 +316,8 @@
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
- mDrawable.setBatteryLevel(level);
mDrawable.setCharging(pluggedIn);
+ mDrawable.setBatteryLevel(level);
mCharging = pluggedIn;
mLevel = level;
updatePercentText();
@@ -315,7 +328,7 @@
@Override
public void onPowerSaveChanged(boolean isPowerSave) {
- mDrawable.setPowerSave(isPowerSave);
+ mDrawable.setPowerSaveEnabled(isPowerSave);
}
private TextView loadPercentView() {
@@ -406,21 +419,24 @@
@Override
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
+ mNonAdaptedSingleToneColor = getColorForDarkIntensity(
+ intensity, mLightModeSingleToneColor, mDarkModeSingleToneColor);
mNonAdaptedForegroundColor = getColorForDarkIntensity(
intensity, mLightModeFillColor, mDarkModeFillColor);
mNonAdaptedBackgroundColor = getColorForDarkIntensity(
intensity, mLightModeBackgroundColor,mDarkModeBackgroundColor);
if (!mUseWallpaperTextColors) {
- updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor);
+ updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor,
+ mNonAdaptedSingleToneColor);
}
}
- private void updateColors(int foregroundColor, int backgroundColor) {
- mDrawable.setColors(foregroundColor, backgroundColor);
- mTextColor = foregroundColor;
+ private void updateColors(int foregroundColor, int backgroundColor, int singleToneColor) {
+ mDrawable.setColors(foregroundColor, backgroundColor, singleToneColor);
+ mTextColor = singleToneColor;
if (mBatteryPercentView != null) {
- mBatteryPercentView.setTextColor(foregroundColor);
+ mBatteryPercentView.setTextColor(singleToneColor);
}
}
@@ -429,7 +445,7 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- String powerSave = mDrawable == null ? null : mDrawable.getPowerSave() + "";
+ String powerSave = mDrawable == null ? null : mDrawable.getPowerSaveEnabled() + "";
CharSequence percent = mBatteryPercentView == null ? null : mBatteryPercentView.getText();
pw.println(" BatteryMeterView:");
pw.println(" mDrawable.getPowerSave: " + powerSave);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 7f76900b..c664a20 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -15,14 +15,11 @@
*/
package com.android.systemui.qs.tiles;
-import android.content.Context;
import android.content.Intent;
-import android.graphics.drawable.Drawable;
import android.service.quicksettings.Tile;
import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.graph.BatteryMeterDrawableBase;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSHost;
@@ -41,6 +38,8 @@
private boolean mCharging;
private boolean mPluggedIn;
+ private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver);
+
@Inject
public BatterySaverTile(QSHost host, BatteryController batteryController) {
super(host);
@@ -84,9 +83,7 @@
protected void handleUpdateState(BooleanState state, Object arg) {
state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
: mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- BatterySaverIcon bsi = new BatterySaverIcon();
- bsi.mState = state.state;
- state.icon = bsi;
+ state.icon = mIcon;
state.label = mContext.getString(R.string.battery_detail_switch_title);
state.contentDescription = state.label;
state.value = mPowerSave;
@@ -106,48 +103,4 @@
mPowerSave = isPowerSave;
refreshState(null);
}
-
- public static class BatterySaverIcon extends Icon {
- private int mState;
-
- @Override
- public Drawable getDrawable(Context context) {
- BatterySaverDrawable b =
- new BatterySaverDrawable(context, QSTileImpl.getColorForState(context, mState));
- b.mState = mState;
- final int pad = context.getResources()
- .getDimensionPixelSize(R.dimen.qs_tile_divider_height);
- b.setPadding(pad, pad, pad, pad);
- return b;
- }
- }
-
- private static class BatterySaverDrawable extends BatteryMeterDrawableBase {
- private int mState;
- private static final int MAX_BATTERY = 100;
-
- BatterySaverDrawable(Context context, int frameColor) {
- super(context, frameColor);
- // Show as full so it's always uniform color
- super.setBatteryLevel(MAX_BATTERY);
- setPowerSave(true);
- setCharging(false);
- setPowerSaveAsColorError(false);
- mPowerSaveAsColorError = true;
- mFramePaint.setColor(0);
- mPowersavePaint.setColor(frameColor);
- mFramePaint.setStrokeWidth(mPowersavePaint.getStrokeWidth());
- mPlusPaint.setColor(frameColor);
- }
-
- @Override
- protected int batteryColorForLevel(int level) {
- return 0;
- }
-
- @Override
- public void setBatteryLevel(int val) {
- // Don't change the actual level, otherwise this won't draw correctly
- }
- }
}