Merge "Toward regularizing color & level across battery indicators." into klp-dev

This commit is contained in:
Daniel Sandler
2013-08-14 06:29:05 +00:00
committed by Android (Google) Code Review
10 changed files with 336 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -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>
</LinearLayout>

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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));
}