summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/drawable-nodpi/lightning.pngbin0 -> 2896 bytes
-rw-r--r--packages/SystemUI/res/layout/quick_settings_tile_battery.xml10
-rw-r--r--packages/SystemUI/res/layout/signal_cluster_view.xml3
-rw-r--r--packages/SystemUI/res/layout/status_bar.xml10
-rw-r--r--packages/SystemUI/res/values/arrays.xml12
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/BatteryMeterView.java302
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java11
10 files changed, 336 insertions, 18 deletions
diff --git a/packages/SystemUI/res/drawable-nodpi/lightning.png b/packages/SystemUI/res/drawable-nodpi/lightning.png
new file mode 100644
index 000000000000..29de3085a533
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/lightning.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
index c41e9b93545b..f3b894cea53a 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
@@ -19,14 +19,14 @@
android:layout_height="match_parent"
android:layout_gravity="top"
android:orientation="vertical">
- <ImageView
+ <com.android.systemui.BatteryMeterView
android:id="@+id/image"
android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
- android:layout_width="@dimen/qs_tile_icon_size"
- android:layout_height="@dimen/qs_tile_icon_size"
+ android:layout_width="22dp"
+ android:layout_height="32dp"
+ android:padding="3dp"
android:layout_gravity="top|center_horizontal"
- android:scaleType="centerInside"
/>
<TextView
style="@style/TextAppearance.QuickSettings.TileView"
@@ -36,4 +36,4 @@
android:layout_gravity="top|center_horizontal"
android:gravity="top|center_horizontal"
/>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index aab5083da3cb..66b06ef789df 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -20,8 +20,9 @@
<com.android.systemui.statusbar.SignalClusterView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_width="wrap_content"
+ android:gravity="center"
android:orientation="horizontal"
>
<FrameLayout
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index b27536d8d9aa..4741cecadf59 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -95,11 +95,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
- <ImageView
+ <!-- battery must be padded below by 1px to match assets -->
+ <com.android.systemui.BatteryMeterView
android:id="@+id/battery"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:paddingStart="4dip"
+ android:layout_height="16dp"
+ android:layout_width="10dp"
+ android:paddingBottom="1px"
+ android:layout_marginStart="4dip"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index cd6aaf604a24..506722d2ef0b 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -40,4 +40,16 @@
<item>@null</item>
</array>
+ <!-- BatteryMeterView parameters -->
+ <array name="batterymeter_color_levels">
+ <item>4</item>
+ <item>15</item>
+ <item>100</item>
+ </array>
+ <array name="batterymeter_color_values">
+ <item>#FFFF0000</item>
+ <item>#FFFE6600</item>
+ <item>#FF3792B4</item>
+ </array>
+
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 803be6ec7e90..04de60fb52b7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -34,4 +34,6 @@
<drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable>
<drawable name="notification_header_bg">#FF000000</drawable>
<color name="notification_panel_scrim_color">#B0000000</color>
+
+ <color name="batterymeter_frame_color">#FF404040</color>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index eec81778ed51..c849aa6d8e96 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -503,4 +503,7 @@
<string name="status_bar_help_title">Notifications appear here</string>
<!-- Body of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
<string name="status_bar_help_text">Access them anytime by swiping down.\nSwipe down again for system controls.</string>
+
+ <!-- Glyph to be overlaid atop the battery when the level is extremely low. Do not translate. -->
+ <string name="battery_meter_very_low_overlay_symbol">!</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
new file mode 100755
index 000000000000..aa4362e2df82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2013 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.systemui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.BatteryManager;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class BatteryMeterView extends View {
+ public static final String TAG = BatteryMeterView.class.getSimpleName();
+ public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+
+ public static final boolean ENABLE_PERCENT = true;
+ public static final boolean SINGLE_DIGIT_PERCENT = false;
+ public static final boolean SHOW_100_PERCENT = false;
+
+ public static final int FULL = 96;
+ public static final int EMPTY = 4;
+
+ int[] mColors;
+
+ boolean mShowPercent = true;
+ Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint;
+ int mButtonHeight;
+ private float mTextHeight, mWarningTextHeight;
+ Drawable mLightning;
+
+ private int mHeight;
+ private int mWidth;
+ private String mWarningString;
+
+ private class BatteryTracker extends BroadcastReceiver {
+ // current battery status
+ int 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));
+
+ 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));
+ 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);
+
+ if (!testmode) return;
+
+ curLevel += incr;
+ if (curLevel == 100) {
+ incr *= -1;
+ }
+ postDelayed(this, 200);
+ }
+ });
+ }
+ }
+ }
+
+ BatteryTracker mTracker = new BatteryTracker();
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(ACTION_LEVEL_TEST);
+ getContext().registerReceiver(mTracker, filter);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ getContext().unregisterReceiver(mTracker);
+ }
+
+ public BatteryMeterView(Context context) {
+ this(context, null, 0);
+ }
+
+ public BatteryMeterView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ final Resources res = context.getResources();
+ TypedArray levels = res.obtainTypedArray(R.array.batterymeter_color_levels);
+ TypedArray colors = res.obtainTypedArray(R.array.batterymeter_color_values);
+
+ final int N = levels.length();
+ mColors = new int[2*N];
+ for (int i=0; i<N; i++) {
+ mColors[2*i] = levels.getInt(i, 0);
+ mColors[2*i+1] = colors.getColor(i, 0);
+ }
+
+ mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
+ context.getContentResolver(), "status_bar_show_battery_percent", 0);
+
+ mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
+
+ mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mFramePaint.setColor(res.getColor(R.color.batterymeter_frame_color));
+ mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBatteryPaint.setColor(0xFF00FF00); // will be replaced by something from mColors
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setColor(0xFFFFFFFF);
+ Typeface font = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
+ 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);
+
+ mLightning = getResources().getDrawable(R.drawable.lightning);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mHeight = h;
+ mWidth = w;
+ mWarningTextPaint.setTextSize(h * 0.75f);
+ mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
+ }
+
+ private int getColorForLevel(int percent) {
+ int thresh, color = 0;
+ for (int i=0; i<mColors.length; i+=2) {
+ thresh = mColors[i];
+ color = mColors[i+1];
+ if (percent <= thresh) return color;
+ }
+ return color;
+ }
+
+ @Override
+ public void draw(Canvas c) {
+ final int level = mTracker.level;
+ float drawFrac = (float) level / 100f;
+ final int pt = getPaddingTop();
+ final int pl = getPaddingLeft();
+ final int pr = getPaddingRight();
+ final int pb = getPaddingBottom();
+ int height = mHeight - pt - pb;
+ int width = mWidth - pl - pr;
+
+ mButtonHeight = (int) (height * 0.12f);
+
+ final RectF frame = new RectF(0, 0, width, height);
+ frame.offset(pl, pt);
+
+ // Log.v("BatteryGauge", String.format("canvas: %dx%d frame: %s",
+ // c.getWidth(), c.getHeight(), frame.toString()));
+
+ final RectF buttonframe = new RectF(
+ frame.left + width * 0.25f,
+ frame.top,
+ frame.right - width * 0.25f,
+ frame.top + mButtonHeight);
+
+ frame.top += mButtonHeight;
+
+ // first, draw the battery shape
+ c.drawRect(frame, mFramePaint);
+
+ // fill 'er up
+ final int pct = mTracker.level;
+ final int color = getColorForLevel(pct);
+ mBatteryPaint.setColor(color);
+
+ if (level >= FULL) {
+ drawFrac = 1f;
+ } else if (level <= EMPTY) {
+ drawFrac = 0f;
+ }
+
+ c.drawRect(buttonframe,
+ drawFrac == 1f ? mBatteryPaint : mFramePaint);
+
+ RectF clip = new RectF(frame);
+ clip.top += (frame.height() * (1f - drawFrac));
+
+ c.save(Canvas.CLIP_SAVE_FLAG);
+ c.clipRect(clip);
+ c.drawRect(frame, mBatteryPaint);
+ c.restore();
+
+ if (level <= EMPTY) {
+ final float x = mWidth * 0.5f;
+ final float y = (mHeight + mWarningTextHeight) * 0.48f;
+ c.drawText(mWarningString, x, y, mWarningTextPaint);
+ } else if (mTracker.plugged) {
+ final Rect r = new Rect(
+ (int)frame.left + width / 4, (int)frame.top + height / 5,
+ (int)frame.right - width / 4, (int)frame.bottom - height / 6);
+ mLightning.setBounds(r);
+ mLightning.draw(c);
+ } else if (mShowPercent && !(mTracker.level == 100 && !SHOW_100_PERCENT)) {
+ mTextPaint.setTextSize(height *
+ (SINGLE_DIGIT_PERCENT ? 0.75f
+ : (mTracker.level == 100 ? 0.38f : 0.5f)));
+ mTextHeight = -mTextPaint.getFontMetrics().ascent;
+
+ final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (pct/10) : pct);
+ final float x = mWidth * 0.5f;
+ final float y = (mHeight + mTextHeight) * 0.47f;
+ c.drawText(str,
+ x,
+ y,
+ mTextPaint);
+
+// Paint pt = new Paint();
+// pt.setStrokeWidth(1f);
+// pt.setStyle(Paint.Style.STROKE);
+// pt.setColor(0xFFFF0000);
+// c.drawRect(x, y-mTextHeight, x+tw, y, pt);
+//
+// Slog.v(TAG, "tw=" + tw + " th=" + mTextHeight);
+//
+// pt.setColor(0xFFFF00FF);
+// c.drawRect(1, 1, mWidth, mHeight, pt);
+ }
+ }
+}
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 74970873f982..62be5d64d54d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -507,7 +507,6 @@ public class PhoneStatusBar extends BaseStatusBar {
// Other icons
mLocationController = new LocationController(mContext); // will post a notification
mBatteryController = new BatteryController(mContext);
- mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
mNetworkController = new NetworkController(mContext);
mBluetoothController = new BluetoothController(mContext);
mRotationLockController = new RotationLockController(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 5233f4289204..5f034a8c752c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -494,7 +494,9 @@ class QuickSettings {
}
// Battery
- final QuickSettingsBasicTile batteryTile = new QuickSettingsBasicTile(mContext);
+ final QuickSettingsTileView batteryTile = (QuickSettingsTileView)
+ inflater.inflate(R.layout.quick_settings_tile, parent, false);
+ batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
batteryTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -506,9 +508,6 @@ class QuickSettings {
public void refreshView(QuickSettingsTileView unused, State state) {
QuickSettingsModel.BatteryState batteryState =
(QuickSettingsModel.BatteryState) state;
- Drawable d = batteryState.pluggedIn
- ? mChargingBatteryLevels
- : mBatteryLevels;
String t;
if (batteryState.batteryLevel == 100) {
t = mContext.getString(R.string.quick_settings_battery_charged_label);
@@ -519,9 +518,7 @@ class QuickSettings {
: mContext.getString(R.string.status_bar_settings_battery_meter_format,
batteryState.batteryLevel);
}
- batteryTile.setImageDrawable(d);
- batteryTile.getImageView().setImageLevel(batteryState.batteryLevel);
- batteryTile.setText(t);
+ ((TextView)batteryTile.findViewById(R.id.text)).setText(t);
batteryTile.setContentDescription(
mContext.getString(R.string.accessibility_quick_settings_battery, t));
}