diff options
| -rw-r--r-- | packages/SystemUI/res/drawable-nodpi/lightning.png | bin | 0 -> 2896 bytes | |||
| -rw-r--r-- | packages/SystemUI/res/layout/quick_settings_tile_battery.xml | 10 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/signal_cluster_view.xml | 3 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/status_bar.xml | 10 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/arrays.xml | 12 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/colors.xml | 2 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/strings.xml | 3 | ||||
| -rwxr-xr-x | packages/SystemUI/src/com/android/systemui/BatteryMeterView.java | 302 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 1 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java | 11 |
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 Binary files differnew file mode 100644 index 000000000000..29de3085a533 --- /dev/null +++ b/packages/SystemUI/res/drawable-nodpi/lightning.png 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)); } |