diff options
Diffstat (limited to 'src/com/android/settings/fuelgauge/BatteryHistoryChart.java')
-rw-r--r-- | src/com/android/settings/fuelgauge/BatteryHistoryChart.java | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java new file mode 100644 index 0000000..95a9fb2 --- /dev/null +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2010 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.settings.fuelgauge; + +import com.android.settings.R; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.os.BatteryStats; +import android.os.SystemClock; +import android.os.BatteryStats.BatteryHistoryRecord; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.view.View; + +public class BatteryHistoryChart extends View { + private static final int SANS = 1; + private static final int SERIF = 2; + private static final int MONOSPACE = 3; + + final Paint mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + + int mFontSize; + + BatteryStats mStats; + long mStatsPeriod; + String mDurationString; + + int mTextAscent; + int mTextDescent; + int mDurationStringWidth; + + int mNumHist; + long mHistStart; + long mHistEnd; + int mBatLow; + int mBatHigh; + + public BatteryHistoryChart(Context context, AttributeSet attrs) { + super(context, attrs); + + mBatteryPaint.setARGB(255, 255, 128, 128); + + mTextPaint.density = getResources().getDisplayMetrics().density; + mTextPaint.setCompatibilityScaling( + getResources().getCompatibilityInfo().applicationScale); + + TypedArray a = + context.obtainStyledAttributes( + attrs, R.styleable.BatteryHistoryChart, 0, 0); + + ColorStateList textColor = null; + int textSize = 15; + int typefaceIndex = -1; + int styleIndex = -1; + + TypedArray appearance = null; + int ap = a.getResourceId(R.styleable.BatteryHistoryChart_android_textAppearance, -1); + if (ap != -1) { + appearance = context.obtainStyledAttributes(ap, + com.android.internal.R.styleable. + TextAppearance); + } + if (appearance != null) { + int n = appearance.getIndexCount(); + for (int i = 0; i < n; i++) { + int attr = appearance.getIndex(i); + + switch (attr) { + case com.android.internal.R.styleable.TextAppearance_textColor: + textColor = appearance.getColorStateList(attr); + break; + + case com.android.internal.R.styleable.TextAppearance_textSize: + textSize = appearance.getDimensionPixelSize(attr, textSize); + break; + + case com.android.internal.R.styleable.TextAppearance_typeface: + typefaceIndex = appearance.getInt(attr, -1); + break; + + case com.android.internal.R.styleable.TextAppearance_textStyle: + styleIndex = appearance.getInt(attr, -1); + break; + } + } + + appearance.recycle(); + } + + int shadowcolor = 0; + float dx=0, dy=0, r=0; + + int n = a.getIndexCount(); + for (int i = 0; i < n; i++) { + int attr = a.getIndex(i); + + switch (attr) { + case R.styleable.BatteryHistoryChart_android_shadowColor: + shadowcolor = a.getInt(attr, 0); + break; + + case R.styleable.BatteryHistoryChart_android_shadowDx: + dx = a.getFloat(attr, 0); + break; + + case R.styleable.BatteryHistoryChart_android_shadowDy: + dy = a.getFloat(attr, 0); + break; + + case R.styleable.BatteryHistoryChart_android_shadowRadius: + r = a.getFloat(attr, 0); + break; + + case R.styleable.BatteryHistoryChart_android_textColor: + textColor = a.getColorStateList(attr); + break; + + case R.styleable.BatteryHistoryChart_android_textSize: + textSize = a.getDimensionPixelSize(attr, textSize); + break; + + case R.styleable.BatteryHistoryChart_android_typeface: + typefaceIndex = a.getInt(attr, typefaceIndex); + break; + + case R.styleable.BatteryHistoryChart_android_textStyle: + styleIndex = a.getInt(attr, styleIndex); + break; + } + } + + mTextPaint.setColor(textColor.getDefaultColor()); + mTextPaint.setTextSize(textSize); + + Typeface tf = null; + switch (typefaceIndex) { + case SANS: + tf = Typeface.SANS_SERIF; + break; + + case SERIF: + tf = Typeface.SERIF; + break; + + case MONOSPACE: + tf = Typeface.MONOSPACE; + break; + } + + setTypeface(tf, styleIndex); + + if (shadowcolor != 0) { + mTextPaint.setShadowLayer(r, dx, dy, shadowcolor); + } + } + + public void setTypeface(Typeface tf, int style) { + if (style > 0) { + if (tf == null) { + tf = Typeface.defaultFromStyle(style); + } else { + tf = Typeface.create(tf, style); + } + + mTextPaint.setTypeface(tf); + // now compute what (if any) algorithmic styling is needed + int typefaceStyle = tf != null ? tf.getStyle() : 0; + int need = style & ~typefaceStyle; + mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0); + mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0); + } else { + mTextPaint.setFakeBoldText(false); + mTextPaint.setTextSkewX(0); + mTextPaint.setTypeface(tf); + } + } + + void setStats(BatteryStats stats) { + mStats = stats; + + long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, + BatteryStats.STATS_UNPLUGGED); + mStatsPeriod = uSecTime; + String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000); + mDurationString = getContext().getString(R.string.battery_stats_on_battery, + durationString); + + BatteryStats.BatteryHistoryRecord rec = stats.getHistory(); + if (rec != null) { + mHistStart = rec.time; + mBatLow = mBatHigh = rec.batteryLevel; + } + int pos = 0; + int lastUnplugged = 0; + mBatLow = 0; + mBatHigh = 100; + while (rec != null) { + pos++; + if ((rec.states&BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG) == 0) { + lastUnplugged = pos; + mHistEnd = rec.time; + } + rec = rec.next; + } + mNumHist = lastUnplugged; + + if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + mDurationStringWidth = (int)mTextPaint.measureText(mDurationString); + mTextAscent = (int)mTextPaint.ascent(); + mTextDescent = (int)mTextPaint.descent(); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + final int width = getWidth(); + final int height = getHeight(); + + final long timeStart = mHistStart; + final long timeChange = mHistEnd-mHistStart; + + final int batLow = mBatLow; + final int batChange = mBatHigh-mBatLow; + + BatteryStats.BatteryHistoryRecord rec = mStats.getHistory(); + int lastX=-1, lastY=-1; + int pos = 0; + final int N = mNumHist; + while (rec != null && pos < N) { + int x = (int)(((rec.time-timeStart)*width)/timeChange); + int y = height-1 - ((rec.batteryLevel-batLow)*height)/batChange; + if (lastX >= 0) { + canvas.drawLine(lastX, lastY, x, y, mBatteryPaint); + } + lastX = x; + lastY = y; + rec = rec.next; + pos++; + } + + canvas.drawText(mDurationString, (width/2) - (mDurationStringWidth/2), + (height/2) - ((mTextDescent-mTextAscent)/2) - mTextAscent, mTextPaint); + } +} |