summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanesh M <daneshm90@gmail.com>2014-11-27 14:17:19 +0100
committerDanesh M <daneshm90@gmail.com>2015-10-28 13:56:26 -0700
commit2e0a11bb0bbf22c32f6e15d97ccac10414ec7b44 (patch)
tree507e61a61d64f34c9f8f4851396118037196aa60
parent7af5d09de49b1c66dd35f86cbc025ee88b34a361 (diff)
downloadframeworks_base-2e0a11bb0bbf22c32f6e15d97ccac10414ec7b44.zip
frameworks_base-2e0a11bb0bbf22c32f6e15d97ccac10414ec7b44.tar.gz
frameworks_base-2e0a11bb0bbf22c32f6e15d97ccac10414ec7b44.tar.bz2
Forward port battery icon options
Squash of following patches from cm-12.1 : Battery text mode (1/2) PS2: Make battery level more fit current solution PS3: Fix displaing battery level inside the icon PS6: Show battery level in status bar header when charging and percentage mode set to inside icon (it's replaced by charging icon) Change-Id: I537c99827e78c796b4980ec7751e5f9b58a88251 Signed-off-by: kecinzer <kecinzer@gmail.com> Forward port battery icon options [1/2] Bring forward the various battery icon options. Portrait, Landscape, Circle, Text. Still retains new options for where to display battery percentage text. Change-Id: Icfc14d989eebde9014538291c24aa76d328df234 Cleanup battery style code * Cleanup commented out code * Fix landscape battery icon padding * Fix landscape battery icon charging indicator * Fix landscape battery icon percentage indicator * Fix circle battery frame color on some black backgrounds * Fix circle battery artifact on low percentage * Fix percentage not shown while charging * Fix percentage always showing on expanded status bar * Fix battery icon showing after reboot on text/hidden modes Change-Id: Ic56878c26e9a3416149eaaa8a9325d56d664e22e SystemUI : Make BatteryMeterView multi-user compatible Change-Id: Ib9a266dc74732b7ad328a6503898a8fbc46af58e Clean up battery handling. Use a single observer for all battery meter and level views, and remove no-longer used callback registrations. Change-Id: I8f9db5e484628d7fbc74fe892d64bef5f08cea24 SystemUI: Fix blinking when reported battery level is 0 Canvas::drawArc has a bug where, if the sweepAngle is 0, depending on the startAngle it will draw an empty or full circle. In the rare cases where the battery reports 0% this would cause the circular meter to blink furiously as it animates through several values of startAngle. As a workaround, let's avoid drawing the percentage bar if the reported battery level is zero. Change-Id: I4c1c767f3616c9d2f8a60df63d64ec1f4e266583 SystemUI: improve circle battery While plugged in, the circle animation would cause the statusbar to keep redrawing itself repeatedly, using up unnecessary cpu cycles, even when idle. - Removed circle animation in status bar - Left animations on keyguard/notificaiton header - Set layer type to hardware when animating for optimized quick drawing - Cleaned up some logic and unnecessary locking - Removed extra work done in each draw - override onDraw instead of draw to let the View system decide when we should draw Change-Id: If0624ab6e3723f4522ebbd9ce583b142c1cb4606 Signed-off-by: Roman Birg <roman@cyngn.com>
-rw-r--r--packages/SystemUI/res/layout/keyguard_status_bar.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar.xml8
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded_header.xml2
-rw-r--r--packages/SystemUI/res/values/cm_arrays.xml27
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java129
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/BatteryMeterView.java1096
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java80
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerService.java1
13 files changed, 1079 insertions, 395 deletions
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index b5f917a..8d33742 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -52,7 +52,7 @@
>
<include layout="@layout/system_icons" />
</FrameLayout>
- <TextView android:id="@+id/battery_level"
+ <com.android.systemui.BatteryLevelTextView android:id="@+id/battery_level_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 2cbe61f..f0932d3 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -95,6 +95,14 @@
<include layout="@layout/system_icons" />
+ <com.android.systemui.BatteryLevelTextView android:id="@+id/battery_level_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="@dimen/header_battery_margin_keyguard"
+ android:textColor="#ffffff"
+ android:textSize="@dimen/battery_level_text_size" />
+
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 12c00cc..783054c 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -85,7 +85,7 @@
>
<include layout="@layout/system_icons" />
</FrameLayout>
- <TextView android:id="@+id/battery_level"
+ <com.android.systemui.BatteryLevelTextView android:id="@+id/battery_level_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
diff --git a/packages/SystemUI/res/values/cm_arrays.xml b/packages/SystemUI/res/values/cm_arrays.xml
new file mode 100644
index 0000000..a9e3654
--- /dev/null
+++ b/packages/SystemUI/res/values/cm_arrays.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012-2014 The CyanogenMod 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <array name="batterymeter_inverted_bolt_points" translatable="false">
+ <item>743</item><item>73</item>
+ <item>743</item><item>292</item>
+ <item>442</item><item>201</item>
+ <item>442</item><item>400</item>
+ <item>0</item><item>20</item>
+ <item>369</item><item>157</item>
+ <item>369</item><item>0</item>
+ </array>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java b/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java
new file mode 100644
index 0000000..4717a0b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 The CyanogenMod 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.systemui;
+
+import com.android.systemui.statusbar.policy.BatteryController;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.TextView;
+
+import java.text.NumberFormat;
+
+public class BatteryLevelTextView extends TextView implements
+ BatteryController.BatteryStateChangeCallback{
+ private BatteryController mBatteryController;
+ private boolean mBatteryCharging;
+ private boolean mForceShow;
+ private boolean mAttached;
+ private int mRequestedVisibility;
+ private int mStyle;
+ private int mPercentMode;
+
+ public BatteryLevelTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mRequestedVisibility = getVisibility();
+ }
+
+ public void setForceShown(boolean forceShow) {
+ mForceShow = forceShow;
+ updateVisibility();
+ }
+
+ public void setBatteryController(BatteryController batteryController) {
+ mBatteryController = batteryController;
+ if (mAttached) {
+ mBatteryController.addStateChangedCallback(this);
+ }
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ mRequestedVisibility = visibility;
+ updateVisibility();
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ // Respect font size setting.
+ setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(R.dimen.battery_level_text_size));
+ }
+
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
+ setText(percentage);
+ if (mBatteryCharging != charging) {
+ mBatteryCharging = charging;
+ updateVisibility();
+ }
+ }
+
+ @Override
+ public void onPowerSaveChanged() {
+ // Not used
+ }
+
+ @Override
+ public void onBatteryStyleChanged(int style, int percentMode) {
+ mStyle = style;
+ mPercentMode = percentMode;
+ updateVisibility();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mBatteryController != null) {
+ mBatteryController.addStateChangedCallback(this);
+ }
+
+ mAttached = true;
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mAttached = false;
+
+ if (mBatteryController != null) {
+ mBatteryController.removeStateChangedCallback(this);
+ }
+ }
+
+ private void updateVisibility() {
+ boolean showNextPercent = mPercentMode == BatteryController.PERCENTAGE_MODE_OUTSIDE
+ || (mBatteryCharging && mPercentMode == BatteryController.PERCENTAGE_MODE_INSIDE);
+ if (mStyle == BatteryController.STYLE_GONE) {
+ showNextPercent = false;
+ } else if (mStyle == BatteryController.STYLE_TEXT) {
+ showNextPercent = true;
+ }
+
+ if (showNextPercent || mForceShow) {
+ super.setVisibility(mRequestedVisibility);
+ } else {
+ super.setVisibility(GONE);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 8cbfa0d..41d4aae 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-14 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.
@@ -16,6 +16,8 @@
package com.android.systemui;
+import com.android.systemui.statusbar.policy.BatteryController;
+
import android.animation.ArgbEvaluator;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -23,32 +25,22 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
-import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
-import com.android.systemui.cm.UserContentObserver;
-import com.android.systemui.statusbar.policy.BatteryController;
-
public class BatteryMeterView extends View implements DemoMode,
BatteryController.BatteryStateChangeCallback {
public static final String TAG = BatteryMeterView.class.getSimpleName();
public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
- public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
-
- private static final boolean SINGLE_DIGIT_PERCENT = false;
private static final int FULL = 96;
@@ -56,25 +48,26 @@ public class BatteryMeterView extends View implements DemoMode,
private final int[] mColors;
- private boolean mShowPercent;
+ protected boolean mShowPercent = true;
private float mButtonHeightFraction;
private float mSubpixelSmoothingLeft;
private float mSubpixelSmoothingRight;
- private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
- private float mTextHeight, mWarningTextHeight;
- private int mIconTint = Color.WHITE;
+
+ public enum BatteryMeterMode {
+ BATTERY_METER_GONE,
+ BATTERY_METER_ICON_PORTRAIT,
+ BATTERY_METER_ICON_LANDSCAPE,
+ BATTERY_METER_CIRCLE,
+ BATTERY_METER_TEXT
+ }
private int mHeight;
private int mWidth;
private String mWarningString;
private final int mCriticalLevel;
- private int mChargeColor;
- private final float[] mBoltPoints;
- private final Path mBoltPath = new Path();
+ private final int mFrameColor;
- private final RectF mFrame = new RectF();
- private final RectF mButtonFrame = new RectF();
- private final RectF mBoltFrame = new RectF();
+ private boolean mAnimationsEnabled;
private final Path mShapePath = new Path();
private final Path mClipPath = new Path();
@@ -89,8 +82,129 @@ public class BatteryMeterView extends View implements DemoMode,
private int mLightModeBackgroundColor;
private int mLightModeFillColor;
- private BatteryTracker mTracker = new BatteryTracker();
- private final SettingObserver mSettingObserver = new SettingObserver();
+ protected BatteryMeterMode mMeterMode = null;
+
+ protected boolean mAttached;
+
+ private boolean mDemoMode;
+ protected BatteryTracker mDemoTracker = new BatteryTracker();
+ protected BatteryTracker mTracker = new BatteryTracker();
+ private BatteryMeterDrawable mBatteryMeterDrawable;
+ private int mIconTint = Color.WHITE;
+
+ private class BatteryTracker extends BroadcastReceiver {
+ public static final int UNKNOWN_LEVEL = -1;
+
+ // current battery status
+ boolean present = true;
+ int level = UNKNOWN_LEVEL;
+ String percentStr;
+ int plugType;
+ boolean plugged;
+ int health;
+ int status;
+ String technology;
+ int voltage;
+ int temperature;
+ boolean testmode = false;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
+
+ level = (int)(100f
+ * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
+ / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+
+ present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+ plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ plugged = plugType != 0;
+ health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,
+ BatteryManager.BATTERY_HEALTH_UNKNOWN);
+ status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
+ voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
+ temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+
+ setContentDescription(
+ context.getString(R.string.accessibility_battery_level, level));
+ if (mBatteryMeterDrawable != null) {
+ setVisibility(View.VISIBLE);
+ invalidate();
+ }
+ } else if (action.equals(ACTION_LEVEL_TEST)) {
+ testmode = true;
+ post(new Runnable() {
+ int curLevel = 0;
+ int incr = 1;
+ int saveLevel = level;
+ int savePlugged = plugType;
+ Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ @Override
+ public void run() {
+ if (curLevel < 0) {
+ testmode = false;
+ dummy.putExtra("level", saveLevel);
+ dummy.putExtra("plugged", savePlugged);
+ dummy.putExtra("testmode", false);
+ } else {
+ dummy.putExtra("level", curLevel);
+ dummy.putExtra("plugged", incr > 0
+ ? BatteryManager.BATTERY_PLUGGED_AC : 0);
+ dummy.putExtra("testmode", true);
+ }
+ getContext().sendBroadcast(dummy);
+
+ if (!testmode) return;
+
+ curLevel += incr;
+ if (curLevel == 100) {
+ incr *= -1;
+ }
+ postDelayed(this, 200);
+ }
+ });
+ }
+ }
+
+ protected boolean shouldIndicateCharging() {
+ if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
+ return true;
+ }
+ if (plugged) {
+ return status == BatteryManager.BATTERY_STATUS_FULL;
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(ACTION_LEVEL_TEST);
+ final Intent sticky = getContext().registerReceiver(mTracker, filter);
+ if (sticky != null) {
+ // preload the battery level
+ mTracker.onReceive(getContext(), sticky);
+ }
+ mBatteryController.addStateChangedCallback(this);
+ mAttached = true;
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ mAttached = false;
+ getContext().unregisterReceiver(mTracker);
+ mBatteryController.removeStateChangedCallback(this);
+ }
public BatteryMeterView(Context context) {
this(context, null, 0);
@@ -106,8 +220,8 @@ public class BatteryMeterView extends View implements DemoMode,
final Resources res = context.getResources();
TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.BatteryMeterView,
defStyle, 0);
- final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
- context.getColor(R.color.batterymeter_frame_color));
+ mFrameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
+ res.getColor(R.color.batterymeter_frame_color));
TypedArray levels = res.obtainTypedArray(R.array.batterymeter_color_levels);
TypedArray colors = res.obtainTypedArray(R.array.batterymeter_color_values);
@@ -120,9 +234,8 @@ public class BatteryMeterView extends View implements DemoMode,
levels.recycle();
colors.recycle();
atts.recycle();
- updateShowPercent();
mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
- mCriticalLevel = mContext.getResources().getInteger(
+ mCriticalLevel = getContext().getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mButtonHeightFraction = context.getResources().getFraction(
R.fraction.battery_button_height_fraction, 1, 1);
@@ -131,66 +244,46 @@ public class BatteryMeterView extends View implements DemoMode,
mSubpixelSmoothingRight = context.getResources().getFraction(
R.fraction.battery_subpixel_smoothing_right, 1, 1);
- mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mFramePaint.setColor(frameColor);
- mFramePaint.setDither(true);
- mFramePaint.setStrokeWidth(0);
- mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
-
- mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mBatteryPaint.setDither(true);
- mBatteryPaint.setStrokeWidth(0);
- mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
-
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
- mTextPaint.setTypeface(font);
- mTextPaint.setTextAlign(Paint.Align.CENTER);
-
- mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mWarningTextPaint.setColor(mColors[1]);
- font = Typeface.create("sans-serif", Typeface.BOLD);
- mWarningTextPaint.setTypeface(font);
- mWarningTextPaint.setTextAlign(Paint.Align.CENTER);
-
- mChargeColor = context.getColor(R.color.batterymeter_charge_color);
-
- mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
- mBoltPoints = loadBoltPoints(res);
-
mDarkModeBackgroundColor =
context.getColor(R.color.dark_mode_icon_color_dual_tone_background);
mDarkModeFillColor = context.getColor(R.color.dark_mode_icon_color_dual_tone_fill);
mLightModeBackgroundColor =
context.getColor(R.color.light_mode_icon_color_dual_tone_background);
mLightModeFillColor = context.getColor(R.color.light_mode_icon_color_dual_tone_fill);
- }
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
+ setAnimationsEnabled(true);
+ }
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(ACTION_LEVEL_TEST);
- final Intent sticky = getContext().registerReceiver(mTracker, filter);
- if (sticky != null) {
- // preload the battery level
- mTracker.onReceive(getContext(), sticky);
+ protected BatteryMeterDrawable createBatteryMeterDrawable(BatteryMeterMode mode) {
+ Resources res = mContext.getResources();
+ switch (mode) {
+ case BATTERY_METER_CIRCLE:
+ return new CircleBatteryMeterDrawable(res);
+ case BATTERY_METER_ICON_LANDSCAPE:
+ return new NormalBatteryMeterDrawable(res, true);
+ case BATTERY_METER_TEXT:
+ case BATTERY_METER_GONE:
+ return null;
+ default:
+ return new NormalBatteryMeterDrawable(res, false);
}
- mBatteryController.addStateChangedCallback(this);
- getContext().getContentResolver().registerContentObserver(
- Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
}
@Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+
+ if (mMeterMode == BatteryMeterMode.BATTERY_METER_CIRCLE) {
+ height += (CircleBatteryMeterDrawable.STROKE_WITH / 3);
+ width = height;
+ } else if (mMeterMode == BatteryMeterMode.BATTERY_METER_TEXT) {
+ onSizeChanged(width, height, 0, 0); // Force a size changed event
+ } else if (mMeterMode.compareTo(BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE) == 0) {
+ width = (int)(height * 1.2f);
+ }
- getContext().unregisterReceiver(mTracker);
- mBatteryController.removeStateChangedCallback(this);
- getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
+ setMeasuredDimension(width, height);
}
public void setBatteryController(BatteryController batteryController) {
@@ -209,35 +302,85 @@ public class BatteryMeterView extends View implements DemoMode,
invalidate();
}
- private static float[] loadBoltPoints(Resources res) {
- final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
- int maxX = 0, maxY = 0;
- for (int i = 0; i < pts.length; i += 2) {
- maxX = Math.max(maxX, pts[i]);
- maxY = Math.max(maxY, pts[i + 1]);
+ public void setAnimationsEnabled(boolean enabled) {
+ if (mAnimationsEnabled != enabled) {
+ mAnimationsEnabled = enabled;
+ setLayerType(mAnimationsEnabled ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, null);
+ invalidate();
}
- final float[] ptsF = new float[pts.length];
- for (int i = 0; i < pts.length; i += 2) {
- ptsF[i] = (float)pts[i] / maxX;
- ptsF[i + 1] = (float)pts[i + 1] / maxY;
+ }
+
+ @Override
+ public void onBatteryStyleChanged(int style, int percentMode) {
+ boolean showInsidePercent = percentMode == BatteryController.PERCENTAGE_MODE_INSIDE;
+ BatteryMeterMode meterMode = BatteryMeterMode.BATTERY_METER_ICON_PORTRAIT;
+
+ switch (style) {
+ case BatteryController.STYLE_CIRCLE:
+ meterMode = BatteryMeterMode.BATTERY_METER_CIRCLE;
+ break;
+ case BatteryController.STYLE_GONE:
+ meterMode = BatteryMeterMode.BATTERY_METER_GONE;
+ showInsidePercent = false;
+ break;
+ case BatteryController.STYLE_ICON_LANDSCAPE:
+ meterMode = BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE;
+ break;
+ case BatteryController.STYLE_TEXT:
+ meterMode = BatteryMeterMode.BATTERY_METER_TEXT;
+ showInsidePercent = false;
+ break;
+ default:
+ break;
}
- return ptsF;
+
+ setMode(meterMode);
+ mShowPercent = showInsidePercent;
+ invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
mHeight = h;
mWidth = w;
- mWarningTextPaint.setTextSize(h * 0.75f);
- mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
+ if (mBatteryMeterDrawable != null) {
+ mBatteryMeterDrawable.onSizeChanged(w, h, oldw, oldh);
+ }
}
- private void updateShowPercent() {
- mShowPercent = 0 != Settings.System.getInt(getContext().getContentResolver(),
- SHOW_PERCENT_SETTING, 0);
+ public void setMode(BatteryMeterMode mode) {
+ if (mMeterMode == mode) {
+ return;
+ }
+
+ mMeterMode = mode;
+ BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
+ if (mode == BatteryMeterMode.BATTERY_METER_GONE ||
+ mode == BatteryMeterMode.BATTERY_METER_TEXT) {
+ setVisibility(View.GONE);
+ mBatteryMeterDrawable = null;
+ } else {
+ if (mBatteryMeterDrawable != null) {
+ mBatteryMeterDrawable.onDispose();
+ }
+ mBatteryMeterDrawable = createBatteryMeterDrawable(mode);
+ if (mMeterMode == BatteryMeterMode.BATTERY_METER_ICON_PORTRAIT ||
+ mMeterMode == BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE) {
+ ((NormalBatteryMeterDrawable)mBatteryMeterDrawable).loadBoltPoints(
+ mContext.getResources());
+ }
+ if (tracker.present) {
+ setVisibility(View.VISIBLE);
+ requestLayout();
+ invalidate();
+ } else {
+ setVisibility(View.GONE);
+ }
+ }
}
- private int getColorForLevel(int percent) {
+ public int getColorForLevel(int percent) {
// If we are in power save mode, always use the normal color.
if (mPowerSaveEnabled) {
@@ -261,13 +404,11 @@ public class BatteryMeterView extends View implements DemoMode,
}
public void setDarkIntensity(float darkIntensity) {
- int backgroundColor = getBackgroundColor(darkIntensity);
- int fillColor = getFillColor(darkIntensity);
- mIconTint = fillColor;
- mFramePaint.setColor(backgroundColor);
- mBoltPaint.setColor(fillColor);
- mChargeColor = fillColor;
- invalidate();
+ if (mBatteryMeterDrawable != null) {
+ int backgroundColor = getBackgroundColor(darkIntensity);
+ int fillColor = getFillColor(darkIntensity);
+ mBatteryMeterDrawable.setDarkIntensity(backgroundColor, fillColor);
+ }
}
private int getBackgroundColor(float darkIntensity) {
@@ -285,261 +426,574 @@ public class BatteryMeterView extends View implements DemoMode,
}
@Override
- public void draw(Canvas c) {
- BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
- final int level = tracker.level;
-
- if (level == BatteryTracker.UNKNOWN_LEVEL) return;
-
- float drawFrac = (float) level / 100f;
- final int pt = getPaddingTop();
- final int pl = getPaddingLeft();
- final int pr = getPaddingRight();
- final int pb = getPaddingBottom();
- final int height = mHeight - pt - pb;
- final int width = mWidth - pl - pr;
-
- final int buttonHeight = (int) (height * mButtonHeightFraction);
-
- mFrame.set(0, 0, width, height);
- mFrame.offset(pl, pt);
-
- // button-frame: area above the battery body
- mButtonFrame.set(
- mFrame.left + Math.round(width * 0.25f),
- mFrame.top,
- mFrame.right - Math.round(width * 0.25f),
- mFrame.top + buttonHeight);
-
- mButtonFrame.top += mSubpixelSmoothingLeft;
- mButtonFrame.left += mSubpixelSmoothingLeft;
- mButtonFrame.right -= mSubpixelSmoothingRight;
-
- // frame: battery body area
- mFrame.top += buttonHeight;
- mFrame.left += mSubpixelSmoothingLeft;
- mFrame.top += mSubpixelSmoothingLeft;
- mFrame.right -= mSubpixelSmoothingRight;
- mFrame.bottom -= mSubpixelSmoothingRight;
-
- // set the battery charging color
- mBatteryPaint.setColor(tracker.plugged ? mChargeColor : getColorForLevel(level));
-
- if (level >= FULL) {
- drawFrac = 1f;
- } else if (level <= mCriticalLevel) {
- drawFrac = 0f;
+ protected void onDraw(Canvas canvas) {
+ if (mBatteryMeterDrawable != null) {
+ BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
+ mBatteryMeterDrawable.onDraw(canvas, tracker);
}
+ }
- final float levelTop = drawFrac == 1f ? mButtonFrame.top
- : (mFrame.top + (mFrame.height() * (1f - drawFrac)));
-
- // define the battery shape
- mShapePath.reset();
- mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
- mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
- mShapePath.lineTo(mButtonFrame.right, mFrame.top);
- mShapePath.lineTo(mFrame.right, mFrame.top);
- mShapePath.lineTo(mFrame.right, mFrame.bottom);
- mShapePath.lineTo(mFrame.left, mFrame.bottom);
- mShapePath.lineTo(mFrame.left, mFrame.top);
- mShapePath.lineTo(mButtonFrame.left, mFrame.top);
- mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
-
- if (tracker.plugged) {
- // define the bolt shape
- final float bl = mFrame.left + mFrame.width() / 4.5f;
- final float bt = mFrame.top + mFrame.height() / 6f;
- final float br = mFrame.right - mFrame.width() / 7f;
- final float bb = mFrame.bottom - mFrame.height() / 10f;
- if (mBoltFrame.left != bl || mBoltFrame.top != bt
- || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
- mBoltFrame.set(bl, bt, br, bb);
- mBoltPath.reset();
- mBoltPath.moveTo(
- mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
- mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
- for (int i = 2; i < mBoltPoints.length; i += 2) {
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
+ @Override
+ public void dispatchDemoCommand(String command, Bundle args) {
+ if (getVisibility() == View.VISIBLE) {
+ if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+ mDemoMode = true;
+ mDemoTracker.level = mTracker.level;
+ mDemoTracker.plugged = mTracker.plugged;
+ } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+ mDemoMode = false;
+ postInvalidate();
+ } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
+ String level = args.getString("level");
+ String plugged = args.getString("plugged");
+ if (level != null) {
+ mDemoTracker.level = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+ }
+ if (plugged != null) {
+ mDemoTracker.plugged = Boolean.parseBoolean(plugged);
+ }
+ postInvalidate();
+ }
+ }
+ }
+
+ protected interface BatteryMeterDrawable {
+ void onDraw(Canvas c, BatteryTracker tracker);
+ void onSizeChanged(int w, int h, int oldw, int oldh);
+ void onDispose();
+ void setDarkIntensity(int backgroundColor, int fillColor);
+ }
+
+ protected class NormalBatteryMeterDrawable implements BatteryMeterDrawable {
+ private static final boolean SINGLE_DIGIT_PERCENT = false;
+ private static final boolean SHOW_100_PERCENT = false;
+
+ private boolean mDisposed;
+
+ protected final boolean mHorizontal;
+
+ private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
+ private float mTextHeight, mWarningTextHeight;
+
+ private int mChargeColor;
+ private final float[] mBoltPoints;
+ private final Path mBoltPath = new Path();
+
+ private final RectF mFrame = new RectF();
+ private final RectF mButtonFrame = new RectF();
+ private final RectF mBoltFrame = new RectF();
+
+ public NormalBatteryMeterDrawable(Resources res, boolean horizontal) {
+ super();
+ mHorizontal = horizontal;
+ mDisposed = false;
+
+ mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mFramePaint.setColor(mFrameColor);
+ mFramePaint.setDither(true);
+ mFramePaint.setStrokeWidth(0);
+ mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
+
+ mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBatteryPaint.setDither(true);
+ mBatteryPaint.setStrokeWidth(0);
+ mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
+ mTextPaint.setTypeface(font);
+ mTextPaint.setTextAlign(Paint.Align.CENTER);
+
+ mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mWarningTextPaint.setColor(mColors[1]);
+ font = Typeface.create("sans-serif", Typeface.BOLD);
+ mWarningTextPaint.setTypeface(font);
+ mWarningTextPaint.setTextAlign(Paint.Align.CENTER);
+
+ mChargeColor = getResources().getColor(R.color.batterymeter_charge_color);
+
+ mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBoltPaint.setColor(res.getColor(R.color.batterymeter_bolt_color));
+ mBoltPoints = loadBoltPoints(res);
+ }
+
+ @Override
+ public void onDraw(Canvas c, BatteryTracker tracker) {
+ if (mDisposed) return;
+
+ final int level = tracker.level;
+
+ if (level == BatteryTracker.UNKNOWN_LEVEL) return;
+
+ float drawFrac = (float) level / 100f;
+ final int pt = getPaddingTop() + (mHorizontal ? (int)(mHeight * 0.12f) : 0);
+ final int pl = getPaddingLeft();
+ final int pr = getPaddingRight();
+ final int pb = getPaddingBottom() + (mHorizontal ? (int)(mHeight * 0.08f) : 0);
+ final int height = mHeight - pt - pb;
+ final int width = mWidth - pl - pr;
+
+ final int buttonHeight = (int) ((mHorizontal ? width : height) * mButtonHeightFraction);
+
+ mFrame.set(0, 0, width, height);
+ mFrame.offset(pl, pt);
+
+ if (mHorizontal) {
+ mButtonFrame.set(
+ /*cover frame border of intersecting area*/
+ width - buttonHeight - mFrame.left,
+ mFrame.top + Math.round(height * 0.25f),
+ mFrame.right,
+ mFrame.bottom - Math.round(height * 0.25f));
+
+ mButtonFrame.top += mSubpixelSmoothingLeft;
+ mButtonFrame.bottom -= mSubpixelSmoothingRight;
+ mButtonFrame.right -= mSubpixelSmoothingRight;
+ } else {
+ // button-frame: area above the battery body
+ mButtonFrame.set(
+ mFrame.left + Math.round(width * 0.25f),
+ mFrame.top,
+ mFrame.right - Math.round(width * 0.25f),
+ mFrame.top + buttonHeight);
+
+ mButtonFrame.top += mSubpixelSmoothingLeft;
+ mButtonFrame.left += mSubpixelSmoothingLeft;
+ mButtonFrame.right -= mSubpixelSmoothingRight;
+ }
+
+ // frame: battery body area
+
+ if (mHorizontal) {
+ mFrame.right -= buttonHeight;
+ } else {
+ mFrame.top += buttonHeight;
+ }
+ mFrame.left += mSubpixelSmoothingLeft;
+ mFrame.top += mSubpixelSmoothingLeft;
+ mFrame.right -= mSubpixelSmoothingRight;
+ mFrame.bottom -= mSubpixelSmoothingRight;
+
+ // set the battery charging color
+ mBatteryPaint.setColor(tracker.plugged ? mChargeColor : getColorForLevel(level));
+
+ if (level >= FULL) {
+ drawFrac = 1f;
+ } else if (level <= mCriticalLevel) {
+ drawFrac = 0f;
+ }
+
+ final float levelTop;
+
+ if (drawFrac == 1f) {
+ if (mHorizontal) {
+ levelTop = mButtonFrame.right;
+ } else {
+ levelTop = mButtonFrame.top;
+ }
+ } else {
+ if (mHorizontal) {
+ levelTop = (mFrame.right - (mFrame.width() * (1f - drawFrac)));
+ } else {
+ levelTop = (mFrame.top + (mFrame.height() * (1f - drawFrac)));
+ }
+ }
+
+ // define the battery shape
+ mShapePath.reset();
+ mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
+ if (mHorizontal) {
+ mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
+ mShapePath.lineTo(mButtonFrame.right, mButtonFrame.bottom);
+ mShapePath.lineTo(mButtonFrame.left, mButtonFrame.bottom);
+ mShapePath.lineTo(mFrame.right, mFrame.bottom);
+ mShapePath.lineTo(mFrame.left, mFrame.bottom);
+ mShapePath.lineTo(mFrame.left, mFrame.top);
+ mShapePath.lineTo(mButtonFrame.left, mFrame.top);
+ mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
+ } else {
+ mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
+ mShapePath.lineTo(mButtonFrame.right, mFrame.top);
+ mShapePath.lineTo(mFrame.right, mFrame.top);
+ mShapePath.lineTo(mFrame.right, mFrame.bottom);
+ mShapePath.lineTo(mFrame.left, mFrame.bottom);
+ mShapePath.lineTo(mFrame.left, mFrame.top);
+ mShapePath.lineTo(mButtonFrame.left, mFrame.top);
+ mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
+ }
+
+ if (tracker.plugged) {
+ // define the bolt shape
+ final float bl = mFrame.left + mFrame.width() / (mHorizontal ? 9f : 4.5f);
+ final float bt = mFrame.top + mFrame.height() / (mHorizontal ? 4.5f : 6f);
+ final float br = mFrame.right - mFrame.width() / (mHorizontal ? 6f : 7f);
+ final float bb = mFrame.bottom - mFrame.height() / (mHorizontal ? 7f : 10f);
+ if (mBoltFrame.left != bl || mBoltFrame.top != bt
+ || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
+ mBoltFrame.set(bl, bt, br, bb);
+ mBoltPath.reset();
+ mBoltPath.moveTo(
+ mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+ for (int i = 2; i < mBoltPoints.length; i += 2) {
+ mBoltPath.lineTo(
+ mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
+ }
mBoltPath.lineTo(
- mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
- mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
+ mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+ }
+
+ float boltPct = mHorizontal ?
+ (mBoltFrame.left - levelTop) / (mBoltFrame.left - mBoltFrame.right) :
+ (mBoltFrame.bottom - levelTop) / (mBoltFrame.bottom - mBoltFrame.top);
+ boltPct = Math.min(Math.max(boltPct, 0), 1);
+ if (boltPct <= BOLT_LEVEL_THRESHOLD) {
+ // draw the bolt if opaque
+ c.drawPath(mBoltPath, mBoltPaint);
+ } else {
+ // otherwise cut the bolt out of the overall shape
+ mShapePath.op(mBoltPath, Path.Op.DIFFERENCE);
+ }
+ }
+
+ // compute percentage text
+ boolean pctOpaque = false;
+ float pctX = 0, pctY = 0;
+ String pctText = null;
+ if (!tracker.plugged && level > mCriticalLevel && mShowPercent) {
+ mTextPaint.setColor(getColorForLevel(level));
+ final float full = mHorizontal ? 0.60f : 0.45f;
+ final float nofull = mHorizontal ? 0.75f : 0.6f;
+ final float single = mHorizontal ? 0.86f : 0.75f;
+ mTextPaint.setTextSize(height *
+ (SINGLE_DIGIT_PERCENT ? single
+ : (tracker.level == 100 ? full : nofull)));
+ mTextHeight = -mTextPaint.getFontMetrics().ascent;
+ pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
+ pctX = mWidth * 0.5f;
+ pctY = (mHeight + mTextHeight) * 0.47f;
+ if (mHorizontal) {
+ pctOpaque = pctX > levelTop;
+ } else {
+ pctOpaque = levelTop > pctY;
+ }
+ if (!pctOpaque) {
+ mTextPath.reset();
+ mTextPaint.getTextPath(pctText, 0, pctText.length(), pctX, pctY, mTextPath);
+ // cut the percentage text out of the overall shape
+ mShapePath.op(mTextPath, Path.Op.DIFFERENCE);
}
- mBoltPath.lineTo(
- mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
- mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
}
- float boltPct = (mBoltFrame.bottom - levelTop) / (mBoltFrame.bottom - mBoltFrame.top);
- boltPct = Math.min(Math.max(boltPct, 0), 1);
- if (boltPct <= BOLT_LEVEL_THRESHOLD) {
- // draw the bolt if opaque
- c.drawPath(mBoltPath, mBoltPaint);
+ // draw the battery shape background
+ c.drawPath(mShapePath, mFramePaint);
+
+ // draw the battery shape, clipped to charging level
+ if (mHorizontal) {
+ mFrame.right = levelTop;
} else {
- // otherwise cut the bolt out of the overall shape
- mShapePath.op(mBoltPath, Path.Op.DIFFERENCE);
+ mFrame.top = levelTop;
+ }
+ mClipPath.reset();
+ mClipPath.addRect(mFrame, Path.Direction.CCW);
+ mShapePath.op(mClipPath, Path.Op.INTERSECT);
+ c.drawPath(mShapePath, mBatteryPaint);
+
+ if (!tracker.plugged) {
+ if (level <= mCriticalLevel) {
+ // draw the warning text
+ final float x = mWidth * 0.5f;
+ final float y = (mHeight + mWarningTextHeight) * 0.48f;
+ c.drawText(mWarningString, x, y, mWarningTextPaint);
+ } else if (pctOpaque) {
+ // draw the percentage text
+ c.drawText(pctText, pctX, pctY, mTextPaint);
+ }
}
}
- // compute percentage text
- boolean pctOpaque = false;
- float pctX = 0, pctY = 0;
- String pctText = null;
- if (!tracker.plugged && level > mCriticalLevel && mShowPercent) {
- mTextPaint.setColor(getColorForLevel(level));
- mTextPaint.setTextSize(height *
- (SINGLE_DIGIT_PERCENT ? 0.75f
- : (tracker.level == 100 ? 0.38f : 0.5f)));
- mTextHeight = -mTextPaint.getFontMetrics().ascent;
- pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
- pctX = mWidth * 0.5f;
- pctY = (mHeight + mTextHeight) * 0.47f;
- pctOpaque = levelTop > pctY;
- if (!pctOpaque) {
- mTextPath.reset();
- mTextPaint.getTextPath(pctText, 0, pctText.length(), pctX, pctY, mTextPath);
- // cut the percentage text out of the overall shape
- mShapePath.op(mTextPath, Path.Op.DIFFERENCE);
- }
+ @Override
+ public void onDispose() {
+ mDisposed = true;
+ }
+
+ @Override
+ public void setDarkIntensity(int backgroundColor, int fillColor) {
+ mIconTint = fillColor;
+ mFramePaint.setColor(backgroundColor);
+ mBoltPaint.setColor(fillColor);
+ mChargeColor = fillColor;
+ invalidate();
+ }
+
+ @Override
+ public void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mHeight = h;
+ mWidth = w;
+ mWarningTextPaint.setTextSize(h * 0.75f);
+ mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
}
- // draw the battery shape background
- c.drawPath(mShapePath, mFramePaint);
-
- // draw the battery shape, clipped to charging level
- mFrame.top = levelTop;
- mClipPath.reset();
- mClipPath.addRect(mFrame, Path.Direction.CCW);
- mShapePath.op(mClipPath, Path.Op.INTERSECT);
- c.drawPath(mShapePath, mBatteryPaint);
-
- if (!tracker.plugged) {
- if (level <= mCriticalLevel) {
- // draw the warning text
- final float x = mWidth * 0.5f;
- final float y = (mHeight + mWarningTextHeight) * 0.48f;
- c.drawText(mWarningString, x, y, mWarningTextPaint);
- } else if (pctOpaque) {
- // draw the percentage text
- c.drawText(pctText, pctX, pctY, mTextPaint);
+ private float[] loadBoltPoints(Resources res) {
+ final int[] pts = res.getIntArray((mHorizontal
+ ? R.array.batterymeter_inverted_bolt_points
+ : R.array.batterymeter_bolt_points));
+ int maxX = 0, maxY = 0;
+ for (int i = 0; i < pts.length; i += 2) {
+ maxX = Math.max(maxX, pts[i]);
+ maxY = Math.max(maxY, pts[i + 1]);
+ }
+ final float[] ptsF = new float[pts.length];
+ for (int i = 0; i < pts.length; i += 2) {
+ ptsF[i] = (float)pts[i] / maxX;
+ ptsF[i + 1] = (float)pts[i + 1] / maxY;
}
+ return ptsF;
}
}
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
+ protected class CircleBatteryMeterDrawable implements BatteryMeterDrawable {
+ private static final boolean SINGLE_DIGIT_PERCENT = false;
+ private static final boolean SHOW_100_PERCENT = false;
- private boolean mDemoMode;
- private BatteryTracker mDemoTracker = new BatteryTracker();
+ private static final int FULL = 96;
- @Override
- public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- mDemoTracker.level = mTracker.level;
- mDemoTracker.plugged = mTracker.plugged;
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- postInvalidate();
- } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
- String level = args.getString("level");
- String plugged = args.getString("plugged");
- if (level != null) {
- mDemoTracker.level = Math.min(Math.max(Integer.parseInt(level), 0), 100);
- }
- if (plugged != null) {
- mDemoTracker.plugged = Boolean.parseBoolean(plugged);
- }
- postInvalidate();
+ public static final float STROKE_WITH = 6.5f;
+
+ private boolean mDisposed;
+
+ private int mAnimOffset;
+ private boolean mIsAnimating; // stores charge-animation status to reliably
+ //remove callbacks
+
+ private int mCircleSize; // draw size of circle
+ private RectF mRectLeft; // contains the precalculated rect used in drawArc(),
+ // derived from mCircleSize
+ private float mTextX, mTextY; // precalculated position for drawText() to appear centered
+
+ private Paint mTextPaint;
+ private Paint mFrontPaint;
+ private Paint mBackPaint;
+ private Paint mBoltPaint;
+ private Paint mWarningTextPaint;
+
+ private final RectF mBoltFrame = new RectF();
+
+ private int mChargeColor;
+ private final float[] mBoltPoints;
+ private final Path mBoltPath = new Path();
+
+ public CircleBatteryMeterDrawable(Resources res) {
+ super();
+ mDisposed = false;
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
+ mTextPaint.setTypeface(font);
+ mTextPaint.setTextAlign(Paint.Align.CENTER);
+
+ mFrontPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mFrontPaint.setStrokeCap(Paint.Cap.BUTT);
+ mFrontPaint.setDither(true);
+ mFrontPaint.setStrokeWidth(0);
+ mFrontPaint.setStyle(Paint.Style.STROKE);
+
+ mBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBackPaint.setColor(res.getColor(R.color.batterymeter_frame_color));
+ mBackPaint.setStrokeCap(Paint.Cap.BUTT);
+ mBackPaint.setDither(true);
+ mBackPaint.setStrokeWidth(0);
+ mBackPaint.setStyle(Paint.Style.STROKE);
+
+ mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mWarningTextPaint.setColor(mColors[1]);
+ font = Typeface.create("sans-serif", Typeface.BOLD);
+ mWarningTextPaint.setTypeface(font);
+ mWarningTextPaint.setTextAlign(Paint.Align.CENTER);
+
+ mChargeColor = getResources().getColor(R.color.batterymeter_charge_color);
+
+ mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBoltPaint.setColor(res.getColor(R.color.batterymeter_bolt_color));
+ mBoltPoints = loadBoltPoints(res);
}
- }
- private final class BatteryTracker extends BroadcastReceiver {
- public static final int UNKNOWN_LEVEL = -1;
+ @Override
+ public void onDraw(Canvas c, BatteryTracker tracker) {
+ if (mDisposed) return;
- // current battery status
- int level = UNKNOWN_LEVEL;
- String percentStr;
- int plugType;
- boolean plugged;
- int health;
- int status;
- String technology;
- int voltage;
- int temperature;
- boolean testmode = false;
+ if (mRectLeft == null) {
+ initSizeBasedStuff();
+ }
+
+ drawCircle(c, tracker, mTextX, mRectLeft);
+ if (mAnimationsEnabled) {
+ updateChargeAnim(tracker);
+ }
+ }
@Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
+ public void onDispose() {
+ mDisposed = true;
+ }
- level = (int)(100f
- * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
- / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+ @Override
+ public void setDarkIntensity(int backgroundColor, int fillColor) {
+ mIconTint = fillColor;
+ mBoltPaint.setColor(fillColor);
+ mChargeColor = fillColor;
+ invalidate();
+ }
- plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
- plugged = plugType != 0;
- health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,
- BatteryManager.BATTERY_HEALTH_UNKNOWN);
- status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
- technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
- voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
- temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+ @Override
+ public void onSizeChanged(int w, int h, int oldw, int oldh) {
+ initSizeBasedStuff();
+ }
- setContentDescription(
- context.getString(R.string.accessibility_battery_level, level));
- postInvalidate();
- } else if (action.equals(ACTION_LEVEL_TEST)) {
- testmode = true;
- post(new Runnable() {
- int curLevel = 0;
- int incr = 1;
- int saveLevel = level;
- int savePlugged = plugType;
- Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
- @Override
- public void run() {
- if (curLevel < 0) {
- testmode = false;
- dummy.putExtra("level", saveLevel);
- dummy.putExtra("plugged", savePlugged);
- dummy.putExtra("testmode", false);
- } else {
- dummy.putExtra("level", curLevel);
- dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
- : 0);
- dummy.putExtra("testmode", true);
- }
- getContext().sendBroadcast(dummy);
+ private float[] loadBoltPoints(Resources res) {
+ final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
+ int maxX = 0, maxY = 0;
+ for (int i = 0; i < pts.length; i += 2) {
+ maxX = Math.max(maxX, pts[i]);
+ maxY = Math.max(maxY, pts[i + 1]);
+ }
+ final float[] ptsF = new float[pts.length];
+ for (int i = 0; i < pts.length; i += 2) {
+ ptsF[i] = (float)pts[i] / maxX;
+ ptsF[i + 1] = (float)pts[i + 1] / maxY;
+ }
+ return ptsF;
+ }
- if (!testmode) return;
+ private void drawCircle(Canvas canvas, BatteryTracker tracker,
+ float textX, RectF drawRect) {
+ boolean unknownStatus = tracker.status == BatteryManager.BATTERY_STATUS_UNKNOWN;
+ int level = tracker.level;
+ Paint paint;
- curLevel += incr;
- if (curLevel == 100) {
- incr *= -1;
- }
- postDelayed(this, 200);
- }
- });
+ if (unknownStatus) {
+ paint = mBackPaint;
+ level = 100; // Draw all the circle;
+ } else {
+ paint = mFrontPaint;
+ paint.setColor(getColorForLevel(level));
+ if (tracker.status == BatteryManager.BATTERY_STATUS_FULL) {
+ level = 100;
+ }
+ }
+
+ // draw thin gray ring first
+ canvas.drawArc(drawRect, 270, 360, false, mBackPaint);
+ if (level != 0) {
+ // draw colored arc representing charge level
+ canvas.drawArc(drawRect, 270 + mAnimOffset, 3.6f * level, false, paint);
+ }
+ // if chosen by options, draw percentage text in the middle
+ // always skip percentage when 100, so layout doesnt break
+ if (unknownStatus) {
+ mTextPaint.setColor(paint.getColor());
+ canvas.drawText("?", textX, mTextY, mTextPaint);
+
+ } else if (tracker.plugged) {
+ canvas.drawPath(mBoltPath, mBoltPaint);
+ } else {
+ if (level > mCriticalLevel
+ && (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT))) {
+ // draw the percentage text
+ String pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
+ mTextPaint.setColor(paint.getColor());
+ canvas.drawText(pctText, textX, mTextY, mTextPaint);
+ } else if (level <= mCriticalLevel) {
+ // draw the warning text
+ canvas.drawText(mWarningString, textX, mTextY, mWarningTextPaint);
+ }
}
}
- }
- private final class SettingObserver extends ContentObserver {
- public SettingObserver() {
- super(new Handler());
+ /**
+ * updates the animation counter
+ * cares for timed callbacks to continue animation cycles
+ * uses mInvalidate for delayed invalidate() callbacks
+ */
+ private void updateChargeAnim(BatteryTracker tracker) {
+ // Stop animation when battery is full or after the meter
+ // rotated back to 0 after unplugging.
+ if (!tracker.shouldIndicateCharging()
+ || tracker.status == BatteryManager.BATTERY_STATUS_FULL
+ || tracker.level == 0) {
+ if (mIsAnimating) {
+ mIsAnimating = false;
+ mAnimOffset = 0;
+ }
+ return;
+ }
+
+ mIsAnimating = true;
+
+ if (mAnimOffset > 360) {
+ mAnimOffset = 0;
+ } else {
+ mAnimOffset += 3;
+ }
+
+ postInvalidateDelayed(50);
}
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- updateShowPercent();
- postInvalidate();
+ /**
+ * initializes all size dependent variables
+ * sets stroke width and text size of all involved paints
+ * YES! i think the method name is appropriate
+ */
+ private void initSizeBasedStuff() {
+ mCircleSize = Math.min(getMeasuredWidth(), getMeasuredHeight());
+ mTextPaint.setTextSize(mCircleSize / 2f);
+ mWarningTextPaint.setTextSize(mCircleSize / 2f);
+
+ float strokeWidth = mCircleSize / STROKE_WITH;
+ mFrontPaint.setStrokeWidth(strokeWidth);
+ mBackPaint.setStrokeWidth(strokeWidth);
+
+ // calculate rectangle for drawArc calls
+ int pLeft = getPaddingLeft();
+ mRectLeft = new RectF(pLeft + strokeWidth / 2.0f, 0 + strokeWidth / 2.0f, mCircleSize
+ - strokeWidth / 2.0f + pLeft, mCircleSize - strokeWidth / 2.0f);
+
+ // calculate Y position for text
+ Rect bounds = new Rect();
+ mTextPaint.getTextBounds("99", 0, "99".length(), bounds);
+ mTextX = mCircleSize / 2.0f + getPaddingLeft();
+ // the +1dp at end of formula balances out rounding issues.works out on all resolutions
+ mTextY = mCircleSize / 2.0f + (bounds.bottom - bounds.top) / 2.0f
+ - strokeWidth / 2.0f + getResources().getDisplayMetrics().density;
+
+ // draw the bolt
+ final float bl = (int) (mRectLeft.left + mRectLeft.width() / 3.2f);
+ final float bt = (int) (mRectLeft.top + mRectLeft.height() / 4f);
+ final float br = (int) (mRectLeft.right - mRectLeft.width() / 5.2f);
+ final float bb = (int) (mRectLeft.bottom - mRectLeft.height() / 8f);
+ if (mBoltFrame.left != bl || mBoltFrame.top != bt
+ || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
+ mBoltFrame.set(bl, bt, br, bb);
+ mBoltPath.reset();
+ mBoltPath.moveTo(
+ mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+ for (int i = 2; i < mBoltPoints.length; i += 2) {
+ mBoltPath.lineTo(
+ mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
+ }
+ mBoltPath.lineTo(
+ mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+ mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+ }
}
}
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index b93fc76..db378d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -29,6 +29,7 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -36,23 +37,18 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import java.text.NumberFormat;
-
/**
* The header group on Keyguard.
*/
-public class KeyguardStatusBarView extends RelativeLayout
- implements BatteryController.BatteryStateChangeCallback {
+public class KeyguardStatusBarView extends RelativeLayout {
- private boolean mBatteryCharging;
private boolean mKeyguardUserSwitcherShowing;
- private boolean mBatteryListening;
private TextView mCarrierLabel;
private View mSystemIconsSuperContainer;
private MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
- private TextView mBatteryLevel;
+ private BatteryLevelTextView mBatteryLevel;
private BatteryController mBatteryController;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -70,12 +66,13 @@ public class KeyguardStatusBarView extends RelativeLayout
mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container);
mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
- mBatteryLevel = (TextView) findViewById(R.id.battery_level);
+ mBatteryLevel = (BatteryLevelTextView) findViewById(R.id.battery_level_text);
mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text);
loadDimens();
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
updateUserSwitcher();
+ updateVisibilities();
}
@Override
@@ -86,8 +83,6 @@ public class KeyguardStatusBarView extends RelativeLayout
mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material));
- mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- getResources().getDimensionPixelSize(R.dimen.battery_level_text_size));
}
private void loadDimens() {
@@ -104,7 +99,7 @@ public class KeyguardStatusBarView extends RelativeLayout
} else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) {
removeView(mMultiUserSwitch);
}
- mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE);
+ mBatteryLevel.setVisibility(View.VISIBLE);
}
private void updateSystemIconsLayoutParams() {
@@ -117,18 +112,6 @@ public class KeyguardStatusBarView extends RelativeLayout
}
}
- public void setListening(boolean listening) {
- if (listening == mBatteryListening) {
- return;
- }
- mBatteryListening = listening;
- if (mBatteryListening) {
- mBatteryController.addStateChangedCallback(this);
- } else {
- mBatteryController.removeStateChangedCallback(this);
- }
- }
-
private void updateUserSwitcher() {
boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null;
mMultiUserSwitch.setClickable(keyguardSwitcherAvailable);
@@ -139,6 +122,7 @@ public class KeyguardStatusBarView extends RelativeLayout
public void setBatteryController(BatteryController batteryController) {
mBatteryController = batteryController;
((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
+ mBatteryLevel.setBatteryController(batteryController);
}
public void setUserSwitcherController(UserSwitcherController controller) {
@@ -154,22 +138,6 @@ public class KeyguardStatusBarView extends RelativeLayout
});
}
- @Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
- String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
- mBatteryLevel.setText(percentage);
- boolean changed = mBatteryCharging != charging;
- mBatteryCharging = charging;
- if (changed) {
- updateVisibilities();
- }
- }
-
- @Override
- public void onPowerSaveChanged() {
- // could not care less
- }
-
public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
mKeyguardUserSwitcher = keyguardUserSwitcher;
mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index ed27eb9..76a9b0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1864,7 +1864,6 @@ public class NotificationPanelView extends PanelView implements
private void setListening(boolean listening) {
mHeader.setListening(listening);
- mKeyguardStatusBar.setListening(listening);
mQsPanel.setListening(listening);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ab036bc..a9bcd75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -121,6 +121,7 @@ import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
+import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.DemoMode;
import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
@@ -315,6 +316,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private DozeServiceHost mDozeServiceHost;
private boolean mScreenOnComingFromTouch;
private PointF mScreenOnTouchLocation;
+ private BatteryMeterView mBatteryView;
+ private BatteryLevelTextView mBatteryTextView;
int mPixelFormat;
Object mQueueLock = new Object();
@@ -991,7 +994,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// Other icons
mLocationController = new LocationControllerImpl(mContext,
mHandlerThread.getLooper()); // will post a notification
- mBatteryController = new BatteryController(mContext);
+ mBatteryController = new BatteryController(mContext, mHandler);
mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
@Override
public void onPowerSaveChanged() {
@@ -1004,6 +1007,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
// noop
}
+ @Override
+ public void onBatteryStyleChanged(int style, int percentMode) {
+ // noop
+ }
});
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
mHotspotController = new HotspotControllerImpl(mContext);
@@ -1086,8 +1093,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mUserInfoController.reloadUserInfo();
mHeader.setBatteryController(mBatteryController);
- ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
- mBatteryController);
+ BatteryMeterView batteryMeterView =
+ ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery));
+ batteryMeterView.setBatteryController(mBatteryController);
+ batteryMeterView.setAnimationsEnabled(false);
+ ((BatteryLevelTextView) mStatusBarView.findViewById(R.id.battery_level_text))
+ .setBatteryController(mBatteryController);
mKeyguardStatusBar.setBatteryController(mBatteryController);
mHeader.setNextAlarmController(mNextAlarmController);
mHeader.setWeatherController(mWeatherController);
@@ -3377,6 +3388,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mSecurityController != null) {
mSecurityController.onUserSwitched(mCurrentUserId);
}
+ if (mBatteryController != null) {
+ mBatteryController.setUserId(mCurrentUserId);
+ }
}
private void resetUserSetupObserver() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 0cc928f..6538ba6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -55,6 +55,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
@@ -71,12 +72,13 @@ import com.android.systemui.tuner.TunerService;
import java.text.NumberFormat;
+import cyanogenmod.providers.CMSettings;
+
/**
* The view to manage the header area in the expanded status bar.
*/
public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener,
- BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback,
- EmergencyListener, WeatherController.Callback {
+ NextAlarmController.NextAlarmChangeCallback, WeatherController.Callback, EmergencyListener {
private boolean mExpanded;
private boolean mListening;
@@ -101,7 +103,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
private Switch mQsDetailHeaderSwitch;
private ImageView mQsDetailHeaderProgress;
private TextView mEmergencyCallsOnly;
- private TextView mBatteryLevel;
+ private BatteryLevelTextView mBatteryLevel;
private TextView mAlarmStatus;
private TextView mWeatherLine1, mWeatherLine2;
@@ -149,6 +151,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
private boolean mDetailTransitioning;
private SettingsObserver mSettingsObserver;
private boolean mShowWeather;
+ private boolean mShowBatteryTextExpanded;
public StatusBarHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -179,7 +182,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
mEmergencyCallsOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
- mBatteryLevel = (TextView) findViewById(R.id.battery_level);
+ mBatteryLevel = (BatteryLevelTextView) findViewById(R.id.battery_level_text);
mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
mAlarmStatus.setOnClickListener(this);
mSignalCluster = findViewById(R.id.signal_cluster);
@@ -234,7 +237,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- FontSizeUtils.updateFontSize(mBatteryLevel, R.dimen.battery_level_text_size);
FontSizeUtils.updateFontSize(mEmergencyCallsOnly,
R.dimen.qs_emergency_calls_only_text_size);
FontSizeUtils.updateFontSize(mDateCollapsed, R.dimen.qs_date_collapsed_size);
@@ -305,6 +307,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
public void setBatteryController(BatteryController batteryController) {
mBatteryController = batteryController;
((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
+ mBatteryLevel.setBatteryController(batteryController);
}
public void setNextAlarmController(NextAlarmController nextAlarmController) {
@@ -366,12 +369,13 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE);
mWeatherContainer.setVisibility(mExpanded && mShowWeather ? View.VISIBLE : View.GONE);
- mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE);
+ mQsDetailHeader.setVisibility(mExpanded && mShowingDetail ? View.VISIBLE : View.INVISIBLE);
if (mSignalCluster != null) {
updateSignalClusterDetachment();
}
mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE);
- mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
+ mBatteryLevel.setForceShown(mExpanded && mShowBatteryTextExpanded);
+ mBatteryLevel.setVisibility(View.VISIBLE);
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
}
@@ -407,11 +411,9 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
private void updateListeners() {
if (mListening) {
mSettingsObserver.observe();
- mBatteryController.addStateChangedCallback(this);
mNextAlarmController.addStateChangedCallback(this);
mWeatherController.addCallback(this);
} else {
- mBatteryController.removeStateChangedCallback(this);
mNextAlarmController.removeStateChangedCallback(this);
mWeatherController.removeCallback(this);
mSettingsObserver.unobserve();
@@ -443,17 +445,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
}
@Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
- String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
- mBatteryLevel.setText(percentage);
- }
-
- @Override
- public void onPowerSaveChanged() {
- // could not care less
- }
-
- @Override
public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
mNextAlarm = nextAlarm;
if (nextAlarm != null) {
@@ -768,6 +759,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
float batteryX;
float batteryY;
float batteryLevelAlpha;
+ float batteryLevelExpandedAlpha;
float settingsAlpha;
float settingsTranslation;
float signalClusterAlpha;
@@ -800,6 +792,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
dateExpandedAlpha = v1.dateExpandedAlpha * (1 - t3) + v2.dateExpandedAlpha * t3;
dateCollapsedAlpha = v1.dateCollapsedAlpha * (1 - t3) + v2.dateCollapsedAlpha * t3;
alarmStatusAlpha = v1.alarmStatusAlpha * (1 - t3) + v2.alarmStatusAlpha * t3;
+ batteryLevelExpandedAlpha =
+ v1.batteryLevelExpandedAlpha * (1 - t3) + v2.batteryLevelExpandedAlpha * t3;
}
}
@@ -925,6 +919,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.STATUS_BAR_SHOW_WEATHER), false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(CMSettings.System.getUriFor(
+ CMSettings.System.STATUS_BAR_BATTERY_STYLE), false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(CMSettings.System.getUriFor(
+ CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT), false, this, UserHandle.USER_ALL);
update();
}
@@ -940,9 +938,26 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
public void update() {
ContentResolver resolver = mContext.getContentResolver();
+ int currentUserId = ActivityManager.getCurrentUser();
+ int batteryStyle = CMSettings.System.getIntForUser(resolver,
+ CMSettings.System.STATUS_BAR_BATTERY_STYLE, 0, currentUserId);
+ boolean showExpandedBatteryPercentage = CMSettings.System.getIntForUser(resolver,
+ CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT, 0, currentUserId) == 0;
+
+ switch (batteryStyle) {
+ case 4: //BATTERY_METER_GONE
+ case 6: //BATTERY_METER_TEXT
+ showExpandedBatteryPercentage = false;
+ break;
+ default:
+ break;
+ }
+
+ mShowBatteryTextExpanded = showExpandedBatteryPercentage;
mShowWeather = Settings.System.getInt(
resolver, Settings.System.STATUS_BAR_SHOW_WEATHER, 1) == 1;
updateVisibilities();
+ requestCaptureValues();
}
}
}
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 d1b69ab..a154544 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -17,10 +17,14 @@
package com.android.systemui.statusbar.policy;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.BatteryManager;
+import android.os.Handler;
import android.os.PowerManager;
import android.util.Log;
@@ -28,10 +32,22 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import cyanogenmod.providers.CMSettings;
+
public class BatteryController extends BroadcastReceiver {
private static final String TAG = "BatteryController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ public static final int STYLE_ICON_PORTRAIT = 0;
+ public static final int STYLE_CIRCLE = 2;
+ public static final int STYLE_GONE = 4;
+ public static final int STYLE_ICON_LANDSCAPE = 5;
+ public static final int STYLE_TEXT = 6;
+
+ public static final int PERCENTAGE_MODE_OFF = 0;
+ public static final int PERCENTAGE_MODE_INSIDE = 1;
+ public static final int PERCENTAGE_MODE_OUTSIDE = 2;
+
private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
private final PowerManager mPowerManager;
@@ -41,7 +57,12 @@ public class BatteryController extends BroadcastReceiver {
private boolean mCharged;
private boolean mPowerSave;
- public BatteryController(Context context) {
+ private int mStyle;
+ private int mPercentMode;
+ private int mUserId;
+ private SettingsObserver mObserver;
+
+ public BatteryController(Context context, Handler handler) {
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
IntentFilter filter = new IntentFilter();
@@ -51,6 +72,14 @@ public class BatteryController extends BroadcastReceiver {
context.registerReceiver(this, filter);
updatePowerSave();
+
+ mObserver = new SettingsObserver(context, handler);
+ mObserver.observe();
+ }
+
+ public void setUserId(int userId) {
+ mUserId = userId;
+ mObserver.observe();
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -65,6 +94,7 @@ public class BatteryController extends BroadcastReceiver {
public void addStateChangedCallback(BatteryStateChangeCallback cb) {
mChangeCallbacks.add(cb);
cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ cb.onBatteryStyleChanged(mStyle, mPercentMode);
}
public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
@@ -121,8 +151,56 @@ public class BatteryController extends BroadcastReceiver {
}
}
+ private void fireSettingsChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onBatteryStyleChanged(mStyle, mPercentMode);
+ }
+ }
+
public interface BatteryStateChangeCallback {
void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
void onPowerSaveChanged();
+ void onBatteryStyleChanged(int style, int percentMode);
}
+
+ private final class SettingsObserver extends ContentObserver {
+ private ContentResolver mResolver;
+ private boolean mRegistered;
+
+ private final Uri STYLE_URI =
+ CMSettings.System.getUriFor(CMSettings.System.STATUS_BAR_BATTERY_STYLE);
+ private final Uri PERCENT_URI =
+ CMSettings.System.getUriFor(CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT);
+
+ public SettingsObserver(Context context, Handler handler) {
+ super(handler);
+ mResolver = context.getContentResolver();
+ }
+
+ public void observe() {
+ if (mRegistered) {
+ mResolver.unregisterContentObserver(this);
+ }
+ mResolver.registerContentObserver(STYLE_URI, false, this, mUserId);
+ mResolver.registerContentObserver(PERCENT_URI, false, this, mUserId);
+ mRegistered = true;
+
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ update();
+ }
+
+ private void update() {
+ mStyle = CMSettings.System.getIntForUser(mResolver,
+ CMSettings.System.STATUS_BAR_BATTERY_STYLE, 0, mUserId);
+ mPercentMode = CMSettings.System.getIntForUser(mResolver,
+ CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT, 0, mUserId);
+
+ fireSettingsChanged();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 71b5de5..1ff5cef 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui.tuner;
-import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
-
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
@@ -105,8 +103,6 @@ public class TunerFragment extends PreferenceFragment {
public void onResume() {
super.onResume();
updateBatteryPct();
- getContext().getContentResolver().registerContentObserver(
- System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
registerPrefs(getPreferenceScreen());
MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true);
@@ -172,8 +168,6 @@ public class TunerFragment extends PreferenceFragment {
private void updateBatteryPct() {
mBatteryPct.setOnPreferenceChangeListener(null);
- mBatteryPct.setChecked(System.getInt(getContext().getContentResolver(),
- SHOW_PERCENT_SETTING, 0) != 0);
mBatteryPct.setOnPreferenceChangeListener(mBatteryPctChange);
}
@@ -194,7 +188,6 @@ public class TunerFragment extends PreferenceFragment {
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean v = (Boolean) newValue;
MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v);
- System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
return true;
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 50234b2..500a828 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -135,7 +135,6 @@ public class TunerService extends SystemUI {
public void clearAll() {
// A couple special cases.
Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
- Settings.System.putString(mContentResolver, BatteryMeterView.SHOW_PERCENT_SETTING, null);
Intent intent = new Intent(DemoMode.ACTION_DEMO);
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
mContext.sendBroadcast(intent);