1ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn/*
2ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn *
4ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * you may not use this file except in compliance with the License.
6ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * You may obtain a copy of the License at
7ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn *
8ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn *
10ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * See the License for the specific language governing permissions and
14ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn * limitations under the License.
15ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn */
16ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
17ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornpackage com.android.settings.fuelgauge;
18ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
19ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport com.android.settings.R;
20ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
21ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.Context;
22ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.res.ColorStateList;
23ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.res.TypedArray;
24ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Canvas;
25ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Paint;
264f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.graphics.Path;
27ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Typeface;
28ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.os.BatteryStats;
29ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.os.SystemClock;
304f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.os.BatteryStats.HistoryItem;
31cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackbornimport android.telephony.ServiceState;
32ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.text.TextPaint;
33ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.util.AttributeSet;
344f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.util.TypedValue;
35ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.view.View;
36ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
37ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornpublic class BatteryHistoryChart extends View {
3819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int CHART_DATA_X_MASK = 0x0000ffff;
3919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int CHART_DATA_BIN_MASK = 0xffff0000;
4019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int CHART_DATA_BIN_SHIFT = 16;
4119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
4219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static class ChartData {
4319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        int[] mColors;
4419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        Paint[] mPaints;
4519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
4619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        int mNumTicks;
4719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        int[] mTicks;
4819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        int mLastBin;
4919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
5019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        void setColors(int[] colors) {
5119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mColors = colors;
5219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mPaints = new Paint[colors.length];
5319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            for (int i=0; i<colors.length; i++) {
5419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mPaints[i] = new Paint();
5519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mPaints[i].setColor(colors[i]);
5619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mPaints[i].setStyle(Paint.Style.FILL);
5719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
5819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
5919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
6019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        void init(int width) {
6119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            if (width > 0) {
62916adce02d5b37038cd78d11a8c884237684f9a8Dianne Hackborn                mTicks = new int[width*2];
6319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            } else {
6419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mTicks = null;
6519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
6619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mNumTicks = 0;
6719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mLastBin = 0;
6819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
6919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
7019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        void addTick(int x, int bin) {
71916adce02d5b37038cd78d11a8c884237684f9a8Dianne Hackborn            if (bin != mLastBin && mNumTicks < mTicks.length) {
7219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mTicks[mNumTicks] = x | bin << CHART_DATA_BIN_SHIFT;
7319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mNumTicks++;
7419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                mLastBin = bin;
7519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
7619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
7719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
7819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        void finish(int width) {
7919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            if (mLastBin != 0) {
8019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                addTick(width, 0);
8119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
8219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
8319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
8419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        void draw(Canvas canvas, int top, int height) {
8519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            int lastBin=0, lastX=0;
8619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            int bottom = top + height;
8719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            for (int i=0; i<mNumTicks; i++) {
8819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                int tick = mTicks[i];
8919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                int x = tick&CHART_DATA_X_MASK;
9019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                int bin = (tick&CHART_DATA_BIN_MASK) >> CHART_DATA_BIN_SHIFT;
9119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                if (lastBin != 0) {
9219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    canvas.drawRect(lastX, top, x, bottom, mPaints[lastBin]);
9319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                }
9419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                lastBin = bin;
9519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                lastX = x;
9619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            }
9719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
9819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        }
9919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    }
10019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
1014f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    static final int SANS = 1;
1024f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    static final int SERIF = 2;
1034f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    static final int MONOSPACE = 3;
1044f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn
1054f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    static final int BATTERY_WARN = 29;
1064f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    static final int BATTERY_CRITICAL = 14;
107ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
10819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    // First value if for phone off; first value is "scanning"; following values
109cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    // are battery stats signal strength buckets.
110cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    static final int NUM_PHONE_SIGNALS = 7;
111cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
1124f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    final Paint mBatteryBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
1134f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    final Paint mBatteryGoodPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
1144f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
1154f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
116cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    final Paint mChargingPaint = new Paint();
117cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    final Paint mScreenOnPaint = new Paint();
118cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    final Paint mGpsOnPaint = new Paint();
119be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    final Paint mWifiRunningPaint = new Paint();
120be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    final Paint mWakeLockPaint = new Paint();
12119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    final ChartData mPhoneSignalChart = new ChartData();
122ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
123ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
12412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mBatLevelPath = new Path();
12512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mBatGoodPath = new Path();
12612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mBatWarnPath = new Path();
12712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mBatCriticalPath = new Path();
12812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mChargingPath = new Path();
12912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    final Path mScreenOnPath = new Path();
130cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    final Path mGpsOnPath = new Path();
131be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    final Path mWifiRunningPath = new Path();
132be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    final Path mWakeLockPath = new Path();
13312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
134ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mFontSize;
135ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
136ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    BatteryStats mStats;
137ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    long mStatsPeriod;
138ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    String mDurationString;
139cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    String mTotalDurationString;
140cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    String mChargingLabel;
141cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    String mScreenOnLabel;
142cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    String mGpsOnLabel;
143be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    String mWifiRunningLabel;
144be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    String mWakeLockLabel;
145cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    String mPhoneSignalLabel;
14612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
147ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mTextAscent;
148ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mTextDescent;
149ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mDurationStringWidth;
150cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mTotalDurationStringWidth;
151cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
152cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    boolean mLargeMode;
153cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
154cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mLineWidth;
155cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mThinLineWidth;
156cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mChargingOffset;
157cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mScreenOnOffset;
158cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mGpsOnOffset;
159be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    int mWifiRunningOffset;
160be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    int mWakeLockOffset;
161cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mPhoneSignalOffset;
162cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mLevelOffset;
163cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mLevelTop;
164cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn    int mLevelBottom;
16519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int PHONE_SIGNAL_X_MASK = CHART_DATA_X_MASK;
16619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int PHONE_SIGNAL_BIN_MASK = CHART_DATA_BIN_MASK;
16719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn    static final int PHONE_SIGNAL_BIN_SHIFT = CHART_DATA_BIN_SHIFT;
168ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
169ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mNumHist;
170ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    long mHistStart;
171ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    long mHistEnd;
172ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mBatLow;
173ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    int mBatHigh;
174be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    boolean mHaveWifi;
175be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn    boolean mHaveGps;
176c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    boolean mHavePhoneSignal;
177ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
178ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    public BatteryHistoryChart(Context context, AttributeSet attrs) {
179ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        super(context, attrs);
180ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
1814f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatteryBackgroundPaint.setARGB(255, 128, 128, 128);
1824f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatteryBackgroundPaint.setStyle(Paint.Style.FILL);
1834f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatteryGoodPaint.setARGB(128, 0, 255, 0);
18412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatteryGoodPaint.setStyle(Paint.Style.STROKE);
1854f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatteryWarnPaint.setARGB(128, 255, 255, 0);
18612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatteryWarnPaint.setStyle(Paint.Style.STROKE);
1874f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatteryCriticalPaint.setARGB(192, 255, 0, 0);
18812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatteryCriticalPaint.setStyle(Paint.Style.STROKE);
18912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mChargingPaint.setARGB(255, 0, 128, 0);
19012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mChargingPaint.setStyle(Paint.Style.STROKE);
19112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mScreenOnPaint.setStyle(Paint.Style.STROKE);
192cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mGpsOnPaint.setStyle(Paint.Style.STROKE);
193be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWifiRunningPaint.setStyle(Paint.Style.STROKE);
194be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWakeLockPaint.setStyle(Paint.Style.STROKE);
19519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        mPhoneSignalChart.setColors(new int[] {
19619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                0x00000000, 0xffa00000, 0xffa0a000, 0xff808020,
19719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                0xff808040, 0xff808060, 0xff008000
19819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        });
199ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
200ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextPaint.density = getResources().getDisplayMetrics().density;
201ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextPaint.setCompatibilityScaling(
202ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                getResources().getCompatibilityInfo().applicationScale);
203ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
204ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        TypedArray a =
205ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            context.obtainStyledAttributes(
206ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                attrs, R.styleable.BatteryHistoryChart, 0, 0);
207ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
208ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        ColorStateList textColor = null;
209ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int textSize = 15;
210ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int typefaceIndex = -1;
211ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int styleIndex = -1;
212ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
213ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        TypedArray appearance = null;
214ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int ap = a.getResourceId(R.styleable.BatteryHistoryChart_android_textAppearance, -1);
215ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        if (ap != -1) {
216ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            appearance = context.obtainStyledAttributes(ap,
217ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                                com.android.internal.R.styleable.
218ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                                TextAppearance);
219ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
220ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        if (appearance != null) {
221ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            int n = appearance.getIndexCount();
222ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            for (int i = 0; i < n; i++) {
223ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                int attr = appearance.getIndex(i);
224ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
225ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                switch (attr) {
226ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case com.android.internal.R.styleable.TextAppearance_textColor:
227ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    textColor = appearance.getColorStateList(attr);
228ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
229ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
230ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case com.android.internal.R.styleable.TextAppearance_textSize:
231ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    textSize = appearance.getDimensionPixelSize(attr, textSize);
232ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
233ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
234ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case com.android.internal.R.styleable.TextAppearance_typeface:
235ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    typefaceIndex = appearance.getInt(attr, -1);
236ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
237ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
238ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case com.android.internal.R.styleable.TextAppearance_textStyle:
239ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    styleIndex = appearance.getInt(attr, -1);
240ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
241ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                }
242ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            }
243ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
244ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            appearance.recycle();
245ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
246ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
247ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int shadowcolor = 0;
248ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        float dx=0, dy=0, r=0;
249ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
250ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int n = a.getIndexCount();
251ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        for (int i = 0; i < n; i++) {
252ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            int attr = a.getIndex(i);
253ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
254ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            switch (attr) {
255ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_shadowColor:
256ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    shadowcolor = a.getInt(attr, 0);
257ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
258ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
259ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_shadowDx:
260ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    dx = a.getFloat(attr, 0);
261ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
262ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
263ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_shadowDy:
264ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    dy = a.getFloat(attr, 0);
265ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
266ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
267ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_shadowRadius:
268ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    r = a.getFloat(attr, 0);
269ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
270ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
271ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_textColor:
272ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    textColor = a.getColorStateList(attr);
273ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
274ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
275ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_textSize:
276ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    textSize = a.getDimensionPixelSize(attr, textSize);
277ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
278ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
279ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_typeface:
280ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    typefaceIndex = a.getInt(attr, typefaceIndex);
281ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
282ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
283ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                case R.styleable.BatteryHistoryChart_android_textStyle:
284ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    styleIndex = a.getInt(attr, styleIndex);
285ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    break;
286ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            }
287ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
288ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
289d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn        a.recycle();
290d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn
291ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextPaint.setColor(textColor.getDefaultColor());
292ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextPaint.setTextSize(textSize);
293ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
294ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        Typeface tf = null;
295ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        switch (typefaceIndex) {
296ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            case SANS:
297ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                tf = Typeface.SANS_SERIF;
298ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                break;
299ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
300ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            case SERIF:
301ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                tf = Typeface.SERIF;
302ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                break;
303ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
304ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            case MONOSPACE:
305ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                tf = Typeface.MONOSPACE;
306ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                break;
307ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
308ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
309ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        setTypeface(tf, styleIndex);
310ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
311ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        if (shadowcolor != 0) {
312ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setShadowLayer(r, dx, dy, shadowcolor);
313ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
314ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    }
315ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
316ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    public void setTypeface(Typeface tf, int style) {
317ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        if (style > 0) {
318ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            if (tf == null) {
319ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                tf = Typeface.defaultFromStyle(style);
320ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            } else {
321ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                tf = Typeface.create(tf, style);
322ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            }
323ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
324ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setTypeface(tf);
325ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            // now compute what (if any) algorithmic styling is needed
326ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            int typefaceStyle = tf != null ? tf.getStyle() : 0;
327ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            int need = style & ~typefaceStyle;
328ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
329ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
330ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        } else {
331ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setFakeBoldText(false);
332ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setTextSkewX(0);
333ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            mTextPaint.setTypeface(tf);
334ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
335ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    }
336ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
337ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    void setStats(BatteryStats stats) {
338ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mStats = stats;
339ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
340ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000,
3414f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn                BatteryStats.STATS_SINCE_CHARGED);
342ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mStatsPeriod = uSecTime;
34349759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn        String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000, true);
344ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mDurationString = getContext().getString(R.string.battery_stats_on_battery,
345ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                durationString);
346cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mChargingLabel = getContext().getString(R.string.battery_stats_charging_label);
347cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mScreenOnLabel = getContext().getString(R.string.battery_stats_screen_on_label);
348cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mGpsOnLabel = getContext().getString(R.string.battery_stats_gps_on_label);
349be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWifiRunningLabel = getContext().getString(R.string.battery_stats_wifi_running_label);
350be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWakeLockLabel = getContext().getString(R.string.battery_stats_wake_lock_label);
351cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label);
352ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
353ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        int pos = 0;
3544f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        int lastInteresting = 0;
3554f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        byte lastLevel = -1;
356ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mBatLow = 0;
357ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mBatHigh = 100;
358be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        int aggrStates = 0;
35919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        boolean first = true;
36019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        if (stats.startIteratingHistoryLocked()) {
36119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            final HistoryItem rec = new HistoryItem();
36219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            while (stats.getNextHistoryLocked(rec)) {
36319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                pos++;
36419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                if (rec.cmd == HistoryItem.CMD_UPDATE) {
36519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    if (first) {
36619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        first = false;
36719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        mHistStart = rec.time;
36819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    }
36919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    if (rec.batteryLevel != lastLevel || pos == 1) {
37019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        lastLevel = rec.batteryLevel;
37119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    }
372b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                    lastInteresting = pos;
373b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                    mHistEnd = rec.time;
37419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    aggrStates |= rec.states;
375b9b7e5c863c9dda33cacc9978ee8c98b6b395d60Dianne Hackborn                }
376ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            }
377ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
3784f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mNumHist = lastInteresting;
379be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mHaveGps = (aggrStates&HistoryItem.STATE_GPS_ON_FLAG) != 0;
380be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mHaveWifi = (aggrStates&HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0;
3818af88fb8387259e51615709b2d1ea0260f7057fdRobert Greenwalt        if (!com.android.settings.Utils.isWifiOnly(getContext())) {
382c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            mHavePhoneSignal = true;
383c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        }
384ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1;
38549759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn        mTotalDurationString = Utils.formatElapsedTime(getContext(), mHistEnd - mHistStart, true);
386ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    }
387ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
388ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    @Override
389ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
390ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
391ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mDurationStringWidth = (int)mTextPaint.measureText(mDurationString);
392cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mTotalDurationStringWidth = (int)mTextPaint.measureText(mTotalDurationString);
393ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextAscent = (int)mTextPaint.ascent();
394ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        mTextDescent = (int)mTextPaint.descent();
395ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    }
396ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
39712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    void finishPaths(int w, int h, int levelh, int startX, int y, Path curLevelPath,
398cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            int lastX, boolean lastCharging, boolean lastScreenOn, boolean lastGpsOn,
39919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            boolean lastWifiRunning, boolean lastWakeLock, Path lastPath) {
40012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        if (curLevelPath != null) {
401c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            if (lastX >= 0 && lastX < w) {
40212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                if (lastPath != null) {
40312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                    lastPath.lineTo(w, y);
40412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                }
40512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                curLevelPath.lineTo(w, y);
40612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            }
407cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            curLevelPath.lineTo(w, mLevelTop+levelh);
408cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            curLevelPath.lineTo(startX, mLevelTop+levelh);
40912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            curLevelPath.close();
41012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
41112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
412cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (lastCharging) {
41312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            mChargingPath.lineTo(w, h-mChargingOffset);
41412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
415cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (lastScreenOn) {
41612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            mScreenOnPath.lineTo(w, h-mScreenOnOffset);
41712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
418cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (lastGpsOn) {
419cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mGpsOnPath.lineTo(w, h-mGpsOnOffset);
420cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
421be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        if (lastWifiRunning) {
422be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mWifiRunningPath.lineTo(w, h-mWifiRunningOffset);
423be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        }
424be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        if (lastWakeLock) {
425be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mWakeLockPath.lineTo(w, h-mWakeLockOffset);
426be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        }
427c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        if (mHavePhoneSignal) {
428c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            mPhoneSignalChart.finish(w);
429c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        }
43012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn    }
43112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
432ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    @Override
433ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
434ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        super.onSizeChanged(w, h, oldw, oldh);
435ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
436cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        int textHeight = mTextDescent - mTextAscent;
437cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
438cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                2, getResources().getDisplayMetrics());
439cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (h > (textHeight*6)) {
440cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLargeMode = true;
441b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn            if (h > (textHeight*15)) {
442b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                // Plenty of room for the chart.
443b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                mLineWidth = textHeight/2;
444b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn            } else {
445b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                // Compress lines to make more room for chart.
446b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                mLineWidth = textHeight/3;
447b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn            }
448cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLevelTop = textHeight + mLineWidth;
44919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mScreenOnPaint.setARGB(255, 32, 64, 255);
45019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mGpsOnPaint.setARGB(255, 32, 64, 255);
45119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mWifiRunningPaint.setARGB(255, 32, 64, 255);
45219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mWakeLockPaint.setARGB(255, 32, 64, 255);
453cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        } else {
454cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLargeMode = false;
455cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLineWidth = mThinLineWidth;
456cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLevelTop = 0;
45719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mScreenOnPaint.setARGB(255, 0, 0, 255);
45819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mGpsOnPaint.setARGB(255, 0, 0, 255);
45919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mWifiRunningPaint.setARGB(255, 0, 0, 255);
46019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            mWakeLockPaint.setARGB(255, 0, 0, 255);
461cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
462cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (mLineWidth <= 0) mLineWidth = 1;
463cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mTextPaint.setStrokeWidth(mThinLineWidth);
464cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mBatteryGoodPaint.setStrokeWidth(mThinLineWidth);
465cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mBatteryWarnPaint.setStrokeWidth(mThinLineWidth);
466cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mBatteryCriticalPaint.setStrokeWidth(mThinLineWidth);
467cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mChargingPaint.setStrokeWidth(mLineWidth);
468cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mScreenOnPaint.setStrokeWidth(mLineWidth);
469cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mGpsOnPaint.setStrokeWidth(mLineWidth);
470be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWifiRunningPaint.setStrokeWidth(mLineWidth);
471be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWakeLockPaint.setStrokeWidth(mLineWidth);
472cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
473cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (mLargeMode) {
474cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            int barOffset = textHeight + mLineWidth;
475be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mChargingOffset = mLineWidth;
476be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mScreenOnOffset = mChargingOffset + barOffset;
477be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mWakeLockOffset = mScreenOnOffset + barOffset;
478be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mWifiRunningOffset = mWakeLockOffset + barOffset;
479a712c3b7b5a17129d016ede082e3e3b2bbd31f9aDianne Hackborn            mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? barOffset : 0);
480a712c3b7b5a17129d016ede082e3e3b2bbd31f9aDianne Hackborn            mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? barOffset : 0);
481b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn            mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? barOffset : 0)
482b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn                    + ((mLineWidth*3)/2);
483c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            if (mHavePhoneSignal) {
484c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani                mPhoneSignalChart.init(w);
485c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            }
486cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        } else {
487be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            mScreenOnOffset = mGpsOnOffset = mWifiRunningOffset
488be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                    = mWakeLockOffset = mLineWidth;
489cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mChargingOffset = mLineWidth*2;
490cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mPhoneSignalOffset = 0;
491cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            mLevelOffset = mLineWidth*3;
492c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            if (mHavePhoneSignal) {
493c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani                mPhoneSignalChart.init(0);
494c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            }
495cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
496cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
4974f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        mBatLevelPath.reset();
49812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatGoodPath.reset();
49912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatWarnPath.reset();
50012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mBatCriticalPath.reset();
50112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mScreenOnPath.reset();
502cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mGpsOnPath.reset();
503be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWifiRunningPath.reset();
504be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        mWakeLockPath.reset();
50512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        mChargingPath.reset();
506ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
507ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        final long timeStart = mHistStart;
508ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        final long timeChange = mHistEnd-mHistStart;
509ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
510ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        final int batLow = mBatLow;
511ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        final int batChange = mBatHigh-mBatLow;
512ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
513cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        final int levelh = h - mLevelOffset - mLevelTop;
514cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        mLevelBottom = mLevelTop + levelh;
51512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
516c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        int x = 0, y = 0, startX = 0, lastX = -1, lastY = -1;
51712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        int i = 0;
51812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        Path curLevelPath = null;
51912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        Path lastLinePath = null;
520cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        boolean lastCharging = false, lastScreenOn = false, lastGpsOn = false;
521be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        boolean lastWifiRunning = false, lastWakeLock = false;
522ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        final int N = mNumHist;
52319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn        if (mStats.startIteratingHistoryLocked()) {
52419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            final HistoryItem rec = new HistoryItem();
52519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn            while (mStats.getNextHistoryLocked(rec) && i < N) {
52619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                if (rec.cmd == BatteryStats.HistoryItem.CMD_UPDATE) {
52719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    x = (int)(((rec.time-timeStart)*w)/timeChange);
52819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange;
52919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
53019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    if (lastX != x) {
53119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        // We have moved by at least a pixel.
53219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        if (lastY != y) {
53319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            // Don't plot changes within a pixel.
53419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            Path path;
53519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            byte value = rec.batteryLevel;
53619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            if (value <= BATTERY_CRITICAL) path = mBatCriticalPath;
53719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            else if (value <= BATTERY_WARN) path = mBatWarnPath;
53819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            else path = mBatGoodPath;
53919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
54019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            if (path != lastLinePath) {
54119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                if (lastLinePath != null) {
54219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                    lastLinePath.lineTo(x, y);
54319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                }
54419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                path.moveTo(x, y);
54519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                lastLinePath = path;
54619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            } else {
54719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                path.lineTo(x, y);
54819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            }
54919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
55019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            if (curLevelPath == null) {
55119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                curLevelPath = mBatLevelPath;
55219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                curLevelPath.moveTo(x, y);
55319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                startX = x;
55419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            } else {
55519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                curLevelPath.lineTo(x, y);
55612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                            }
55719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            lastX = x;
55819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                            lastY = y;
55912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                        }
56056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
56119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn
56256247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    final boolean charging =
56356247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        (rec.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0;
56456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (charging != lastCharging) {
56556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (charging) {
56656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mChargingPath.moveTo(x, h-mChargingOffset);
56756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
56856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mChargingPath.lineTo(x, h-mChargingOffset);
56912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                        }
57056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        lastCharging = charging;
57156247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
572cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
57356247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    final boolean screenOn =
57456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        (rec.states&HistoryItem.STATE_SCREEN_ON_FLAG) != 0;
57556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (screenOn != lastScreenOn) {
57656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (screenOn) {
57756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mScreenOnPath.moveTo(x, h-mScreenOnOffset);
57856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
57956247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mScreenOnPath.lineTo(x, h-mScreenOnOffset);
58012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn                        }
58156247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        lastScreenOn = screenOn;
58256247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
583cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
58456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    final boolean gpsOn =
58556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        (rec.states&HistoryItem.STATE_GPS_ON_FLAG) != 0;
58656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (gpsOn != lastGpsOn) {
58756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (gpsOn) {
58856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mGpsOnPath.moveTo(x, h-mGpsOnOffset);
58956247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
59056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mGpsOnPath.lineTo(x, h-mGpsOnOffset);
591cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                        }
59256247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        lastGpsOn = gpsOn;
59356247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
594cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
59556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    final boolean wifiRunning =
59656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        (rec.states&HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0;
59756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (wifiRunning != lastWifiRunning) {
59856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (wifiRunning) {
59956247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mWifiRunningPath.moveTo(x, h-mWifiRunningOffset);
60056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
60156247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mWifiRunningPath.lineTo(x, h-mWifiRunningOffset);
602cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                        }
60356247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        lastWifiRunning = wifiRunning;
60456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
605cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
60656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    final boolean wakeLock =
60756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        (rec.states&HistoryItem.STATE_WAKE_LOCK_FLAG) != 0;
60856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (wakeLock != lastWakeLock) {
60956247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (wakeLock) {
61056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mWakeLockPath.moveTo(x, h-mWakeLockOffset);
61156247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
61256247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            mWakeLockPath.lineTo(x, h-mWakeLockOffset);
613be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                        }
61456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        lastWakeLock = wakeLock;
61556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    }
616be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn
61756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                    if (mLargeMode && mHavePhoneSignal) {
61856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        int bin;
61956247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        if (((rec.states&HistoryItem.STATE_PHONE_STATE_MASK)
62056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                                >> HistoryItem.STATE_PHONE_STATE_SHIFT)
62156247a63fc621815ecff82a278ad8553174922a0Todd Poynor                                == ServiceState.STATE_POWER_OFF) {
62256247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            bin = 0;
62356247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else if ((rec.states&HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) {
62456247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            bin = 1;
62556247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        } else {
62656247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            bin = (rec.states&HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
62756247a63fc621815ecff82a278ad8553174922a0Todd Poynor                                    >> HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT;
62856247a63fc621815ecff82a278ad8553174922a0Todd Poynor                            bin += 2;
629be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                        }
63056247a63fc621815ecff82a278ad8553174922a0Todd Poynor                        mPhoneSignalChart.addTick(x, bin);
631be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                    }
632be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn
63319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                } else if (rec.cmd != BatteryStats.HistoryItem.CMD_OVERFLOW) {
63419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                    if (curLevelPath != null) {
63519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX,
63619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning,
63719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                                lastWakeLock, lastLinePath);
63819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        lastX = lastY = -1;
63919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        curLevelPath = null;
64019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        lastLinePath = null;
64119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                        lastCharging = lastScreenOn = lastGpsOn = lastWakeLock = false;
6424f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn                    }
6434f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn                }
64412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn
64519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                i++;
646ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn            }
647ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn        }
648ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn
649c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        finishPaths(w, h, levelh, startX, lastY, curLevelPath, lastX,
650be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning,
65119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn                lastWakeLock, lastLinePath);
6524f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    }
6534f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn
6544f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    @Override
6554f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn    protected void onDraw(Canvas canvas) {
6564f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        super.onDraw(canvas);
65774809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani
6584f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        final int width = getWidth();
6594f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        final int height = getHeight();
66074809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani        final boolean layoutRtl = isLayoutRtl();
66174809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani        final int textStartX = layoutRtl ? width : 0;
66274809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani        mTextPaint.setTextAlign(layoutRtl ? Paint.Align.RIGHT : Paint.Align.LEFT);
66374809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani
6644f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        canvas.drawPath(mBatLevelPath, mBatteryBackgroundPaint);
665cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (mLargeMode) {
66674809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            int durationHalfWidth = mTotalDurationStringWidth / 2;
66774809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            if (layoutRtl) durationHalfWidth = -durationHalfWidth;
66874809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mDurationString, textStartX, -mTextAscent + (mLineWidth / 2),
669cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    mTextPaint);
67074809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mTotalDurationString, (width / 2) - durationHalfWidth,
671cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    mLevelBottom - mTextAscent + mThinLineWidth, mTextPaint);
672cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        } else {
67374809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            int durationHalfWidth = mDurationStringWidth / 2;
67474809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            if (layoutRtl) durationHalfWidth = -durationHalfWidth;
67574809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mDurationString, (width / 2) - durationHalfWidth,
67674809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani                    (height / 2) - ((mTextDescent - mTextAscent) / 2) - mTextAscent, mTextPaint);
677cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
67812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        if (!mBatGoodPath.isEmpty()) {
67912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            canvas.drawPath(mBatGoodPath, mBatteryGoodPaint);
68012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
68112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        if (!mBatWarnPath.isEmpty()) {
68212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            canvas.drawPath(mBatWarnPath, mBatteryWarnPaint);
68312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
68412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        if (!mBatCriticalPath.isEmpty()) {
68512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint);
68612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        }
687c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        if (mHavePhoneSignal) {
688b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn            int top = height-mPhoneSignalOffset - (mLineWidth/2);
689c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            mPhoneSignalChart.draw(canvas, top, mLineWidth);
690c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        }
69112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn        if (!mScreenOnPath.isEmpty()) {
69212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn            canvas.drawPath(mScreenOnPath, mScreenOnPaint);
6934f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn        }
694cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (!mChargingPath.isEmpty()) {
695cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            canvas.drawPath(mChargingPath, mChargingPaint);
696cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
697be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        if (mHaveGps) {
698be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            if (!mGpsOnPath.isEmpty()) {
699be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                canvas.drawPath(mGpsOnPath, mGpsOnPaint);
700be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            }
701be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        }
702be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        if (mHaveWifi) {
703be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            if (!mWifiRunningPath.isEmpty()) {
704be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                canvas.drawPath(mWifiRunningPath, mWifiRunningPaint);
705be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            }
706be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        }
707be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn        if (!mWakeLockPath.isEmpty()) {
708be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            canvas.drawPath(mWakeLockPath, mWakeLockPaint);
709cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
710cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn
711cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        if (mLargeMode) {
712c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            if (mHavePhoneSignal) {
71374809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani                canvas.drawText(mPhoneSignalLabel, textStartX,
714c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani                        height - mPhoneSignalOffset - mTextDescent, mTextPaint);
715c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            }
716be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            if (mHaveGps) {
71774809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani                canvas.drawText(mGpsOnLabel, textStartX,
718be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                        height - mGpsOnOffset - mTextDescent, mTextPaint);
719be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            }
720be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            if (mHaveWifi) {
72174809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani                canvas.drawText(mWifiRunningLabel, textStartX,
722be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                        height - mWifiRunningOffset - mTextDescent, mTextPaint);
723be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn            }
72474809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mWakeLockLabel, textStartX,
725be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn                    height - mWakeLockOffset - mTextDescent, mTextPaint);
72674809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mChargingLabel, textStartX,
727cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    height - mChargingOffset - mTextDescent, mTextPaint);
72874809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani            canvas.drawText(mScreenOnLabel, textStartX,
729cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    height - mScreenOnOffset - mTextDescent, mTextPaint);
730cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            canvas.drawLine(0, mLevelBottom+(mThinLineWidth/2), width,
731cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    mLevelBottom+(mThinLineWidth/2), mTextPaint);
732cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            canvas.drawLine(0, mLevelTop, 0,
733cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                    mLevelBottom+(mThinLineWidth/2), mTextPaint);
734cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            for (int i=0; i<10; i++) {
735cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                int y = mLevelTop + ((mLevelBottom-mLevelTop)*i)/10;
736cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn                canvas.drawLine(0, y, mThinLineWidth*2, y, mTextPaint);
737cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn            }
738cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn        }
739ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn    }
740ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn}
741