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 190be7598cb8c8cf6808b336204632615c5f26298fDianne Hackbornimport android.content.Intent; 206fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackbornimport android.graphics.Bitmap; 215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport android.graphics.DashPathEffect; 220be7598cb8c8cf6808b336204632615c5f26298fDianne Hackbornimport android.os.BatteryManager; 235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport android.provider.Settings; 245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport android.text.format.DateFormat; 25525f2bdfd2b5293ba4338a9664da9a21d468ba0aDianne Hackbornimport android.text.format.Formatter; 265a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport android.util.Log; 275a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport android.util.TimeUtils; 28ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport com.android.settings.R; 297253df35a09d8d61ececedbb66179171802e42a7Elliott Hughesimport com.android.settings.Utils; 30ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 31ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.Context; 32ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.res.ColorStateList; 33ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.content.res.TypedArray; 34ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Canvas; 35ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Paint; 364f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.graphics.Path; 37ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.graphics.Typeface; 38ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.os.BatteryStats; 39ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.os.SystemClock; 404f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.os.BatteryStats.HistoryItem; 41cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackbornimport android.telephony.ServiceState; 42ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.text.TextPaint; 43ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.util.AttributeSet; 444f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackbornimport android.util.TypedValue; 45ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornimport android.view.View; 465a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport libcore.icu.LocaleData; 475a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 485a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport java.util.ArrayList; 495a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackbornimport java.util.Calendar; 50a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglioimport java.util.Locale; 51ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 52ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackbornpublic class BatteryHistoryChart extends View { 535a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn static final boolean DEBUG = false; 545a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn static final String TAG = "BatteryHistoryChart"; 555a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 5619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn static final int CHART_DATA_X_MASK = 0x0000ffff; 5719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn static final int CHART_DATA_BIN_MASK = 0xffff0000; 5819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn static final int CHART_DATA_BIN_SHIFT = 16; 5919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 6019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn static class ChartData { 6119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int[] mColors; 6219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn Paint[] mPaints; 6319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 6419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int mNumTicks; 6519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int[] mTicks; 6619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int mLastBin; 6719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 6819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn void setColors(int[] colors) { 6919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mColors = colors; 7019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mPaints = new Paint[colors.length]; 7119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn for (int i=0; i<colors.length; i++) { 7219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mPaints[i] = new Paint(); 7319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mPaints[i].setColor(colors[i]); 7419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mPaints[i].setStyle(Paint.Style.FILL); 7519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 7619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 7719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 7819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn void init(int width) { 7919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (width > 0) { 80916adce02d5b37038cd78d11a8c884237684f9a8Dianne Hackborn mTicks = new int[width*2]; 8119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } else { 8219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mTicks = null; 8319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 8419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mNumTicks = 0; 8519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mLastBin = 0; 8619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 8719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 8819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn void addTick(int x, int bin) { 89916adce02d5b37038cd78d11a8c884237684f9a8Dianne Hackborn if (bin != mLastBin && mNumTicks < mTicks.length) { 901cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn mTicks[mNumTicks] = (x&CHART_DATA_X_MASK) | (bin<<CHART_DATA_BIN_SHIFT); 9119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mNumTicks++; 9219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn mLastBin = bin; 9319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 9419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 9519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 9619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn void finish(int width) { 9719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (mLastBin != 0) { 9819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn addTick(width, 0); 9919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 10019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 10119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 10219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn void draw(Canvas canvas, int top, int height) { 10319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int lastBin=0, lastX=0; 10419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int bottom = top + height; 10519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn for (int i=0; i<mNumTicks; i++) { 10619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int tick = mTicks[i]; 10719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int x = tick&CHART_DATA_X_MASK; 10819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn int bin = (tick&CHART_DATA_BIN_MASK) >> CHART_DATA_BIN_SHIFT; 10919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (lastBin != 0) { 11019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn canvas.drawRect(lastX, top, x, bottom, mPaints[lastBin]); 11119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 11219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastBin = bin; 11319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastX = x; 11419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 11519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 11619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 11719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 11819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 1194f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn static final int SANS = 1; 1204f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn static final int SERIF = 2; 1214f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn static final int MONOSPACE = 3; 1224f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn 12319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn // First value if for phone off; first value is "scanning"; following values 124cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn // are battery stats signal strength buckets. 125cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn static final int NUM_PHONE_SIGNALS = 7; 126cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 1274f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final Paint mBatteryBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1284f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final Paint mBatteryGoodPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1294f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1304f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1315a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Paint mTimeRemainPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 132cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn final Paint mChargingPaint = new Paint(); 133cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn final Paint mScreenOnPaint = new Paint(); 134cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn final Paint mGpsOnPaint = new Paint(); 135be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn final Paint mWifiRunningPaint = new Paint(); 13655985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn final Paint mCpuRunningPaint = new Paint(); 1375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Paint mDateLinePaint = new Paint(); 13819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn final ChartData mPhoneSignalChart = new ChartData(); 139ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 1400be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final TextPaint mHeaderTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 1415a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Paint mDebugRectPaint = new Paint(); 1420be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 14312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mBatLevelPath = new Path(); 14412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mBatGoodPath = new Path(); 14512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mBatWarnPath = new Path(); 14612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mBatCriticalPath = new Path(); 1475a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Path mTimeRemainPath = new Path(); 14812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mChargingPath = new Path(); 14912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn final Path mScreenOnPath = new Path(); 150cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn final Path mGpsOnPath = new Path(); 151be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn final Path mWifiRunningPath = new Path(); 15255985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn final Path mCpuRunningPath = new Path(); 1535a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Path mDateLinePath = new Path(); 15412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn 155ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn BatteryStats mStats; 1560be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn Intent mBatteryBroadcast; 157ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn long mStatsPeriod; 158c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn int mBatteryLevel; 1595a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn String mMaxPercentLabelString; 1605a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn String mMinPercentLabelString; 161ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn String mDurationString; 1620be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn String mChargeLabelString; 1630be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn String mChargeDurationString; 1640be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn String mDrainString; 165cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn String mChargingLabel; 166cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn String mScreenOnLabel; 167cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn String mGpsOnLabel; 168be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn String mWifiRunningLabel; 16955985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn String mCpuRunningLabel; 170cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn String mPhoneSignalLabel; 1717158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 1727158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int mChartMinHeight; 1737158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int mHeaderHeight; 1747158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 1757158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int mBatteryWarnLevel; 1767158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int mBatteryCriticalLevel; 1777158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 178ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mTextAscent; 179ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mTextDescent; 1800be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int mHeaderTextAscent; 1810be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int mHeaderTextDescent; 1825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mMaxPercentLabelStringWidth; 1835a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mMinPercentLabelStringWidth; 184ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mDurationStringWidth; 1850be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int mChargeLabelStringWidth; 1860be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int mChargeDurationStringWidth; 1870be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int mDrainStringWidth; 188cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 189cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn boolean mLargeMode; 190cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 1915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mLastWidth = -1; 1925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mLastHeight = -1; 1935a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 194cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mLineWidth; 195cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mThinLineWidth; 196cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mChargingOffset; 197cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mScreenOnOffset; 198cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mGpsOnOffset; 199be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn int mWifiRunningOffset; 20055985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn int mCpuRunningOffset; 201cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mPhoneSignalOffset; 202cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mLevelOffset; 203cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mLevelTop; 204cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int mLevelBottom; 2055a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mLevelLeft; 2065a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int mLevelRight; 2073bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn 208ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mNumHist; 209ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn long mHistStart; 2105a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long mHistDataEnd; 211ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn long mHistEnd; 2125a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long mStartWallTime; 2135a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long mEndDataWallTime; 2145a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long mEndWallTime; 2155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn boolean mDischarging; 216ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mBatLow; 217ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int mBatHigh; 218be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn boolean mHaveWifi; 219be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn boolean mHaveGps; 220c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani boolean mHavePhoneSignal; 2210be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2225a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final ArrayList<TimeLabel> mTimeLabels = new ArrayList<TimeLabel>(); 2235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final ArrayList<DateLabel> mDateLabels = new ArrayList<DateLabel>(); 2245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 2256fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn Bitmap mBitmap; 2266fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn Canvas mCanvas; 2276fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 2280be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn static class TextAttrs { 2290be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn ColorStateList textColor = null; 2300be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int textSize = 15; 2310be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int typefaceIndex = -1; 2320be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int styleIndex = -1; 2330be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2340be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn void retrieve(Context context, TypedArray from, int index) { 2350be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn TypedArray appearance = null; 2360be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int ap = from.getResourceId(index, -1); 2370be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn if (ap != -1) { 2380be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn appearance = context.obtainStyledAttributes(ap, 2390be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn com.android.internal.R.styleable.TextAppearance); 2400be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2410be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn if (appearance != null) { 2420be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int n = appearance.getIndexCount(); 2430be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn for (int i = 0; i < n; i++) { 2440be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int attr = appearance.getIndex(i); 2450be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2460be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn switch (attr) { 2470be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case com.android.internal.R.styleable.TextAppearance_textColor: 2480be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn textColor = appearance.getColorStateList(attr); 2490be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2500be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2510be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case com.android.internal.R.styleable.TextAppearance_textSize: 2520be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn textSize = appearance.getDimensionPixelSize(attr, textSize); 2530be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2540be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2550be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case com.android.internal.R.styleable.TextAppearance_typeface: 2560be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn typefaceIndex = appearance.getInt(attr, -1); 2570be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2580be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2590be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case com.android.internal.R.styleable.TextAppearance_textStyle: 2600be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn styleIndex = appearance.getInt(attr, -1); 2610be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2620be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2630be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2640be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2650be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn appearance.recycle(); 2660be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2670be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2680be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2690be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn void apply(Context context, TextPaint paint) { 2700be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.density = context.getResources().getDisplayMetrics().density; 2710be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setCompatibilityScaling( 2720be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn context.getResources().getCompatibilityInfo().applicationScale); 2730be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2740be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setColor(textColor.getDefaultColor()); 2750be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setTextSize(textSize); 2760be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2770be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn Typeface tf = null; 2780be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn switch (typefaceIndex) { 2790be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case SANS: 2800be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn tf = Typeface.SANS_SERIF; 2810be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2820be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2830be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case SERIF: 2840be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn tf = Typeface.SERIF; 2850be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2860be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2870be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn case MONOSPACE: 2880be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn tf = Typeface.MONOSPACE; 2890be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn break; 2900be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2910be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2920be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn setTypeface(paint, tf, styleIndex); 2930be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 2940be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 2950be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn public void setTypeface(TextPaint paint, Typeface tf, int style) { 2960be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn if (style > 0) { 2970be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn if (tf == null) { 2980be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn tf = Typeface.defaultFromStyle(style); 2990be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } else { 3000be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn tf = Typeface.create(tf, style); 3010be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 3020be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 3030be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setTypeface(tf); 3040be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn // now compute what (if any) algorithmic styling is needed 3050be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int typefaceStyle = tf != null ? tf.getStyle() : 0; 3060be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int need = style & ~typefaceStyle; 3070be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setFakeBoldText((need & Typeface.BOLD) != 0); 3080be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0); 3090be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } else { 3100be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setFakeBoldText(false); 3110be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setTextSkewX(0); 3120be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn paint.setTypeface(tf); 3130be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 3140be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 3150be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn } 3160be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 3175a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn static class TimeLabel { 3185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final int x; 3195a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final String label; 3205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final int width; 3215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 322a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio TimeLabel(TextPaint paint, int x, Calendar cal, boolean use24hr) { 3235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn this.x = x; 324a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio final String bestFormat = DateFormat.getBestDateTimePattern( 325a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio Locale.getDefault(), use24hr ? "km" : "ha"); 326a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio label = DateFormat.format(bestFormat, cal).toString(); 3275a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn width = (int)paint.measureText(label); 3285a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 3295a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 3305a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 3315a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn static class DateLabel { 3325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final int x; 3335a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final String label; 3345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final int width; 3355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 336a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio DateLabel(TextPaint paint, int x, Calendar cal, boolean dayFirst) { 3375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn this.x = x; 338a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio final String bestFormat = DateFormat.getBestDateTimePattern( 339a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio Locale.getDefault(), dayFirst ? "dM" : "Md"); 340a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio label = DateFormat.format(bestFormat, cal).toString(); 3415a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn width = (int)paint.measureText(label); 3425a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 3435a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 3445a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 345ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn public BatteryHistoryChart(Context context, AttributeSet attrs) { 346ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn super(context, attrs); 3477158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 3486fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (DEBUG) Log.d(TAG, "New BatteryHistoryChart!"); 3496fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 3507158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryWarnLevel = mContext.getResources().getInteger( 3517158e6299210d08f82c29135c001652508b79dfbDianne Hackborn com.android.internal.R.integer.config_lowBatteryWarningLevel); 3527158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryCriticalLevel = mContext.getResources().getInteger( 3537158e6299210d08f82c29135c001652508b79dfbDianne Hackborn com.android.internal.R.integer.config_criticalBatteryWarningLevel); 3547158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 3555a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3565a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 2, getResources().getDisplayMetrics()); 3575a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 3587158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryBackgroundPaint.setColor(0xFF009688); 3594f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn mBatteryBackgroundPaint.setStyle(Paint.Style.FILL); 3607158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryGoodPaint.setARGB(128, 0, 128, 0); 36112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatteryGoodPaint.setStyle(Paint.Style.STROKE); 3627158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryWarnPaint.setARGB(128, 128, 128, 0); 36312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatteryWarnPaint.setStyle(Paint.Style.STROKE); 3647158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryCriticalPaint.setARGB(192, 128, 0, 0); 36512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatteryCriticalPaint.setStyle(Paint.Style.STROKE); 3667158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mTimeRemainPaint.setColor(0xFFCED7BB); 3675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPaint.setStyle(Paint.Style.FILL); 36812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mChargingPaint.setStyle(Paint.Style.STROKE); 36912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mScreenOnPaint.setStyle(Paint.Style.STROKE); 370cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mGpsOnPaint.setStyle(Paint.Style.STROKE); 371be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mWifiRunningPaint.setStyle(Paint.Style.STROKE); 37255985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn mCpuRunningPaint.setStyle(Paint.Style.STROKE); 37368f005fbd48f18cdab0168ba92b8fd40776edc1eDianne Hackborn mPhoneSignalChart.setColors(com.android.settings.Utils.BADNESS_COLORS); 3745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDebugRectPaint.setARGB(255, 255, 0, 0); 3755a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDebugRectPaint.setStyle(Paint.Style.STROKE); 3763bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mScreenOnPaint.setColor(0xFF009688); 3773bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mGpsOnPaint.setColor(0xFF009688); 3783bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mWifiRunningPaint.setColor(0xFF009688); 3793bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mCpuRunningPaint.setColor(0xFF009688); 3803bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mChargingPaint.setColor(0xFF009688); 3815a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 382ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn TypedArray a = 383ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn context.obtainStyledAttributes( 384ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn attrs, R.styleable.BatteryHistoryChart, 0, 0); 385ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 3860be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final TextAttrs mainTextAttrs = new TextAttrs(); 3870be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final TextAttrs headTextAttrs = new TextAttrs(); 3880be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.retrieve(context, a, R.styleable.BatteryHistoryChart_android_textAppearance); 3890be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.retrieve(context, a, R.styleable.BatteryHistoryChart_headerAppearance); 390ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 391ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int shadowcolor = 0; 392ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn float dx=0, dy=0, r=0; 393ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 394ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int n = a.getIndexCount(); 395ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn for (int i = 0; i < n; i++) { 396ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int attr = a.getIndex(i); 397ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 398ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn switch (attr) { 399ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_shadowColor: 400ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn shadowcolor = a.getInt(attr, 0); 401ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 402ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 403ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_shadowDx: 404ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn dx = a.getFloat(attr, 0); 405ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 406ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 407ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_shadowDy: 408ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn dy = a.getFloat(attr, 0); 409ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 410ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 411ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_shadowRadius: 412ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn r = a.getFloat(attr, 0); 413ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 414ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 415ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_textColor: 4160be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.textColor = a.getColorStateList(attr); 4170be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.textColor = a.getColorStateList(attr); 418ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 419ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 420ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_textSize: 4210be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.textSize = a.getDimensionPixelSize(attr, mainTextAttrs.textSize); 4220be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.textSize = a.getDimensionPixelSize(attr, headTextAttrs.textSize); 423ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 424ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 425ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_typeface: 4260be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.typefaceIndex = a.getInt(attr, mainTextAttrs.typefaceIndex); 4270be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.typefaceIndex = a.getInt(attr, headTextAttrs.typefaceIndex); 428ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 429ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 430ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn case R.styleable.BatteryHistoryChart_android_textStyle: 4310be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.styleIndex = a.getInt(attr, mainTextAttrs.styleIndex); 4320be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.styleIndex = a.getInt(attr, headTextAttrs.styleIndex); 433ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn break; 4347158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 4357158e6299210d08f82c29135c001652508b79dfbDianne Hackborn case R.styleable.BatteryHistoryChart_barPrimaryColor: 4367158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mBatteryBackgroundPaint.setColor(a.getInt(attr, 0)); 4373bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mScreenOnPaint.setColor(a.getInt(attr, 0)); 4383bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mGpsOnPaint.setColor(a.getInt(attr, 0)); 4393bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mWifiRunningPaint.setColor(a.getInt(attr, 0)); 4403bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mCpuRunningPaint.setColor(a.getInt(attr, 0)); 4413bd46a70c1e63c16542fcec1b87b99693cbbbf1eDianne Hackborn mChargingPaint.setColor(a.getInt(attr, 0)); 4427158e6299210d08f82c29135c001652508b79dfbDianne Hackborn break; 4437158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 4447158e6299210d08f82c29135c001652508b79dfbDianne Hackborn case R.styleable.BatteryHistoryChart_barPredictionColor: 4457158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mTimeRemainPaint.setColor(a.getInt(attr, 0)); 4467158e6299210d08f82c29135c001652508b79dfbDianne Hackborn break; 4477158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 4487158e6299210d08f82c29135c001652508b79dfbDianne Hackborn case R.styleable.BatteryHistoryChart_chartMinHeight: 4497158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mChartMinHeight = a.getDimensionPixelSize(attr, 0); 4507158e6299210d08f82c29135c001652508b79dfbDianne Hackborn break; 451ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 452ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 453ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 454d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn a.recycle(); 455d2be882d8f2e5acd8a5806c649ba4640249cf4baDianne Hackborn 4560be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mainTextAttrs.apply(context, mTextPaint); 4570be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn headTextAttrs.apply(context, mHeaderTextPaint); 4580be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 4595a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePaint.set(mTextPaint); 4605a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePaint.setStyle(Paint.Style.STROKE); 4615a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int hairlineWidth = mThinLineWidth/2; 4625a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (hairlineWidth < 1) { 4635a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn hairlineWidth = 1; 4645a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 4655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePaint.setStrokeWidth(hairlineWidth); 4665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePaint.setPathEffect(new DashPathEffect(new float[] { 4675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mThinLineWidth * 2, mThinLineWidth * 2 }, 0)); 4685a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 469ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn if (shadowcolor != 0) { 470ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mTextPaint.setShadowLayer(r, dx, dy, shadowcolor); 4710be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextPaint.setShadowLayer(r, dx, dy, shadowcolor); 472ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 473ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 4745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 4750be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn void setStats(BatteryStats stats, Intent broadcast) { 476ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mStats = stats; 4770be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mBatteryBroadcast = broadcast; 4780be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 4796fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (DEBUG) Log.d(TAG, "Setting stats..."); 4806fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 4810be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000; 4820be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 4830be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn long uSecTime = mStats.computeBatteryRealtime(elapsedRealtimeUs, 4844f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn BatteryStats.STATS_SINCE_CHARGED); 485ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mStatsPeriod = uSecTime; 486cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mChargingLabel = getContext().getString(R.string.battery_stats_charging_label); 487cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mScreenOnLabel = getContext().getString(R.string.battery_stats_screen_on_label); 488cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mGpsOnLabel = getContext().getString(R.string.battery_stats_gps_on_label); 489be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mWifiRunningLabel = getContext().getString(R.string.battery_stats_wifi_running_label); 49055985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn mCpuRunningLabel = getContext().getString(R.string.battery_stats_wake_lock_label); 491cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label); 4925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 4937253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes mMaxPercentLabelString = Utils.formatPercentage(100); 4947253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes mMinPercentLabelString = Utils.formatPercentage(0); 4955a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 496c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn mBatteryLevel = com.android.settings.Utils.getBatteryLevel(mBatteryBroadcast); 4975a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long remainingTimeUs = 0; 4985a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDischarging = true; 499b11c97379918fce423bfb0b96a8319a8e698845dDianne Hackborn if (mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) == 0) { 5005a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs); 5015a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (drainTime > 0) { 5025a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn remainingTimeUs = drainTime; 5035a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn String timeString = Formatter.formatShortElapsedTime(getContext(), 5045a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn drainTime / 1000); 5055a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargeLabelString = getContext().getResources().getString( 506c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn R.string.power_discharging_duration, mBatteryLevel, timeString); 5075a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 5087253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes mChargeLabelString = Utils.formatPercentage(mBatteryLevel); 5095a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 5105a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 5115a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs); 5125a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final String statusLabel = com.android.settings.Utils.getBatteryStatus(getResources(), 5135a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mBatteryBroadcast); 514b11c97379918fce423bfb0b96a8319a8e698845dDianne Hackborn final int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS, 515b11c97379918fce423bfb0b96a8319a8e698845dDianne Hackborn BatteryManager.BATTERY_STATUS_UNKNOWN); 5165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { 5175a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDischarging = false; 5185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn remainingTimeUs = chargeTime; 5195a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn String timeString = Formatter.formatShortElapsedTime(getContext(), 5205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn chargeTime / 1000); 5217158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int plugType = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); 5227158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int resId; 5237158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { 5247158e6299210d08f82c29135c001652508b79dfbDianne Hackborn resId = R.string.power_charging_duration_ac; 5257158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { 5267158e6299210d08f82c29135c001652508b79dfbDianne Hackborn resId = R.string.power_charging_duration_usb; 5277158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { 5287158e6299210d08f82c29135c001652508b79dfbDianne Hackborn resId = R.string.power_charging_duration_wireless; 5297158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else { 5307158e6299210d08f82c29135c001652508b79dfbDianne Hackborn resId = R.string.power_charging_duration; 5317158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 5325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargeLabelString = getContext().getResources().getString( 533c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn resId, mBatteryLevel, timeString); 5345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 5355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargeLabelString = getContext().getResources().getString( 536c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn R.string.power_charging, mBatteryLevel, statusLabel); 5375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 5385a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 5395a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDrainString = ""; 5405a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargeDurationString = ""; 5411cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn setContentDescription(mChargeLabelString); 5425a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 543ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn int pos = 0; 5444f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn int lastInteresting = 0; 5454f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn byte lastLevel = -1; 546ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mBatLow = 0; 547ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mBatHigh = 100; 5485a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mStartWallTime = 0; 5495a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mEndDataWallTime = 0; 5505a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mEndWallTime = 0; 5515a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mHistStart = 0; 5525a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mHistEnd = 0; 5535a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long lastWallTime = 0; 5545a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long lastRealtime = 0; 555be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn int aggrStates = 0; 55696debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn int aggrStates2 = 0; 55719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn boolean first = true; 55819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (stats.startIteratingHistoryLocked()) { 55919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn final HistoryItem rec = new HistoryItem(); 56019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn while (stats.getNextHistoryLocked(rec)) { 56119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn pos++; 5625a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (first) { 5635a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn first = false; 5645a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mHistStart = rec.time; 5655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 5665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (rec.cmd == HistoryItem.CMD_CURRENT_TIME 5675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn || rec.cmd == HistoryItem.CMD_RESET) { 5682b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn // If there is a ridiculously large jump in time, then we won't be 5692b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn // able to create a good chart with that data, so just ignore the 5702b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn // times we got before and pretend like our data extends back from 5712b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn // the time we have now. 57294aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn // Also, if we are getting a time change and we are less than 5 minutes 57394aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn // since the start of the history real time, then also use this new 57494aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn // time to compute the base time, since whatever time we had before is 57594aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn // pretty much just noise. 57694aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn if (rec.currentTime > (lastWallTime+(180*24*60*60*1000L)) 57794aae9afd18c17848aed68addd19d93c937c7555Dianne Hackborn || rec.time < (mHistStart+(5*60*1000L))) { 5782b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn mStartWallTime = 0; 5792b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } 5805a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastWallTime = rec.currentTime; 5815a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastRealtime = rec.time; 5825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mStartWallTime == 0) { 5832b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn mStartWallTime = lastWallTime - (lastRealtime-mHistStart); 58419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 5855a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 5865a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (rec.isDeltaData()) { 58719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (rec.batteryLevel != lastLevel || pos == 1) { 58819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastLevel = rec.batteryLevel; 58919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 590b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn lastInteresting = pos; 5915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mHistDataEnd = rec.time; 59219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn aggrStates |= rec.states; 59396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn aggrStates2 |= rec.states2; 594b9b7e5c863c9dda33cacc9978ee8c98b6b395d60Dianne Hackborn } 595ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 596ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 5975a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mHistEnd = mHistDataEnd + (remainingTimeUs/1000); 5985a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mEndDataWallTime = lastWallTime + mHistDataEnd - lastRealtime; 5995a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mEndWallTime = mEndDataWallTime + (remainingTimeUs/1000); 6004f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn mNumHist = lastInteresting; 601be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mHaveGps = (aggrStates&HistoryItem.STATE_GPS_ON_FLAG) != 0; 60296debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn mHaveWifi = (aggrStates2&HistoryItem.STATE2_WIFI_RUNNING_FLAG) != 0 60396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn || (aggrStates&(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG 60496debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn |HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG 60596debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn |HistoryItem.STATE_WIFI_SCAN_FLAG)) != 0; 6068af88fb8387259e51615709b2d1ea0260f7057fdRobert Greenwalt if (!com.android.settings.Utils.isWifiOnly(getContext())) { 607c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani mHavePhoneSignal = true; 608c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 609ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1; 610ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 611ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 612ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn @Override 613ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 6145a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mMaxPercentLabelStringWidth = (int)mTextPaint.measureText(mMaxPercentLabelString); 6155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mMinPercentLabelStringWidth = (int)mTextPaint.measureText(mMinPercentLabelString); 6160be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mDrainStringWidth = (int)mHeaderTextPaint.measureText(mDrainString); 6170be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mChargeLabelStringWidth = (int)mHeaderTextPaint.measureText(mChargeLabelString); 6180be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mChargeDurationStringWidth = (int)mHeaderTextPaint.measureText(mChargeDurationString); 619ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mTextAscent = (int)mTextPaint.ascent(); 620ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn mTextDescent = (int)mTextPaint.descent(); 6210be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextAscent = (int)mHeaderTextPaint.ascent(); 6220be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextDescent = (int)mHeaderTextPaint.descent(); 6237158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int headerTextHeight = mHeaderTextDescent - mHeaderTextAscent; 6247158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mHeaderHeight = headerTextHeight*2 - mTextAscent; 6257158e6299210d08f82c29135c001652508b79dfbDianne Hackborn setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), 6267158e6299210d08f82c29135c001652508b79dfbDianne Hackborn getDefaultSize(mChartMinHeight+mHeaderHeight, heightMeasureSpec)); 627ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 628ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn 62912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn void finishPaths(int w, int h, int levelh, int startX, int y, Path curLevelPath, 630cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int lastX, boolean lastCharging, boolean lastScreenOn, boolean lastGpsOn, 63155985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn boolean lastWifiRunning, boolean lastCpuRunning, Path lastPath) { 63212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (curLevelPath != null) { 633c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn if (lastX >= 0 && lastX < w) { 63412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (lastPath != null) { 63512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn lastPath.lineTo(w, y); 63612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 63712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn curLevelPath.lineTo(w, y); 63812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 639cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn curLevelPath.lineTo(w, mLevelTop+levelh); 640cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn curLevelPath.lineTo(startX, mLevelTop+levelh); 64112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn curLevelPath.close(); 64212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 64312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn 644cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (lastCharging) { 64512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mChargingPath.lineTo(w, h-mChargingOffset); 64612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 647cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (lastScreenOn) { 64812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mScreenOnPath.lineTo(w, h-mScreenOnOffset); 64912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 650cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (lastGpsOn) { 651cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mGpsOnPath.lineTo(w, h-mGpsOnOffset); 652cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 653be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (lastWifiRunning) { 654be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mWifiRunningPath.lineTo(w, h-mWifiRunningOffset); 655be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 65655985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn if (lastCpuRunning) { 65755985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn mCpuRunningPath.lineTo(w, h - mCpuRunningOffset); 658be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 659c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani if (mHavePhoneSignal) { 660c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani mPhoneSignalChart.finish(w); 661c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 66212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 6635a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 6645a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn private boolean is24Hour() { 6655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn return DateFormat.is24HourFormat(getContext()); 6665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 6675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 6685a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn private boolean isDayFirst() { 6695a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn String value = Settings.System.getString(mContext.getContentResolver(), 6705a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn Settings.System.DATE_FORMAT); 6715a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (value == null) { 6725a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn LocaleData d = LocaleData.get(mContext.getResources().getConfiguration().locale); 6735a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn value = d.shortDateFormat4; 6745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 6755a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn return value.indexOf('M') > value.indexOf('d'); 6765a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 6775a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 6785a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn /* 6795a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn private void buildTime() { 6805a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context); 6815a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final Calendar now = Calendar.getInstance(); 6825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDummyDate.setTimeZone(now.getTimeZone()); 6835a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // We use December 31st because it's unambiguous when demonstrating the date format. 6845a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // We use 13:00 so we can demonstrate the 12/24 hour options. 6855a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDummyDate.set(now.get(Calendar.YEAR), 11, 31, 13, 0, 0); 6865a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn Date dummyDate = mDummyDate.getTime(); 6875a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime())); 6885a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeZone.setSummary(getTimeZoneText(now.getTimeZone(), true)); 6895a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDatePref.setSummary(shortDateFormat.format(now.getTime())); 6905a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateFormat.setSummary(shortDateFormat.format(dummyDate)); 6915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate)); 6925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 6935a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 6945a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn */ 6955a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 696ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn @Override 697ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn protected void onSizeChanged(int w, int h, int oldw, int oldh) { 698ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn super.onSizeChanged(w, h, oldw, oldh); 6995a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 7005a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "onSizeChanged: " + oldw + "x" + oldh + " to " + w + "x" + h); 7015a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 7025a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mLastWidth == w && mLastHeight == h) { 7035a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn return; 7045a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 7055a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 706a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn if (mLastWidth == 0 || mLastHeight == 0) { 707a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn return; 708a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn } 709a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn 7106fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (DEBUG) Log.d(TAG, "Rebuilding chart for: " + w + "x" + h); 7116fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 712a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn mLastWidth = w; 713a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn mLastHeight = h; 7146fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn mBitmap = null; 7156fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn mCanvas = null; 716a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn 717cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn int textHeight = mTextDescent - mTextAscent; 7187158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (h > ((textHeight*10)+mChartMinHeight)) { 719cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mLargeMode = true; 720b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn if (h > (textHeight*15)) { 721b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn // Plenty of room for the chart. 722b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn mLineWidth = textHeight/2; 723b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn } else { 724b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn // Compress lines to make more room for chart. 725b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn mLineWidth = textHeight/3; 726b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn } 727cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } else { 728cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mLargeMode = false; 729cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mLineWidth = mThinLineWidth; 730cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 731cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (mLineWidth <= 0) mLineWidth = 1; 7325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 7337158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mLevelTop = mHeaderHeight; 7345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelLeft = mMaxPercentLabelStringWidth + mThinLineWidth*3; 7355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelRight = w; 7365a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int levelWidth = mLevelRight-mLevelLeft; 7375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 738cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mTextPaint.setStrokeWidth(mThinLineWidth); 739cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mBatteryGoodPaint.setStrokeWidth(mThinLineWidth); 740cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mBatteryWarnPaint.setStrokeWidth(mThinLineWidth); 741cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mBatteryCriticalPaint.setStrokeWidth(mThinLineWidth); 742cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mChargingPaint.setStrokeWidth(mLineWidth); 743cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mScreenOnPaint.setStrokeWidth(mLineWidth); 744cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mGpsOnPaint.setStrokeWidth(mLineWidth); 745be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mWifiRunningPaint.setStrokeWidth(mLineWidth); 74655985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn mCpuRunningPaint.setStrokeWidth(mLineWidth); 7475a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDebugRectPaint.setStrokeWidth(1); 7485a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 7495a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int fullBarOffset = textHeight + mLineWidth; 750cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 751cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (mLargeMode) { 752be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mChargingOffset = mLineWidth; 7535a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mScreenOnOffset = mChargingOffset + fullBarOffset; 7545a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mCpuRunningOffset = mScreenOnOffset + fullBarOffset; 7555a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mWifiRunningOffset = mCpuRunningOffset + fullBarOffset; 7565a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? fullBarOffset : 0); 7575a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? fullBarOffset : 0); 7585a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? fullBarOffset : 0) 7595a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn + mLineWidth*2 + mLineWidth/2; 760c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani if (mHavePhoneSignal) { 761c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani mPhoneSignalChart.init(w); 762c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 763cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } else { 764be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mScreenOnOffset = mGpsOnOffset = mWifiRunningOffset 7655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn = mCpuRunningOffset = mChargingOffset = mPhoneSignalOffset = 0; 7665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelOffset = fullBarOffset + mThinLineWidth*4; 767c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani if (mHavePhoneSignal) { 768c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani mPhoneSignalChart.init(0); 769c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 770cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 771cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 7724f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn mBatLevelPath.reset(); 77312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatGoodPath.reset(); 77412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatWarnPath.reset(); 7755a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.reset(); 77612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mBatCriticalPath.reset(); 77712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mScreenOnPath.reset(); 778cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mGpsOnPath.reset(); 779be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn mWifiRunningPath.reset(); 78055985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn mCpuRunningPath.reset(); 78112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn mChargingPath.reset(); 7825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 783a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn mTimeLabels.clear(); 784a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn mDateLabels.clear(); 785a32d81797f0e8164f922d9626ed6258c93b72772Dianne Hackborn 7865a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long walltimeStart = mStartWallTime; 787c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn final long walltimeChange = mEndWallTime > walltimeStart 788c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn ? (mEndWallTime-walltimeStart) : 1; 7892b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn long curWalltime = mStartWallTime; 7905a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn long lastRealtime = 0; 7915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 792ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn final int batLow = mBatLow; 793ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn final int batChange = mBatHigh-mBatLow; 7945a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 795cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn final int levelh = h - mLevelOffset - mLevelTop; 796cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn mLevelBottom = mLevelTop + levelh; 7975a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 7985a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int x = mLevelLeft, y = 0, startX = mLevelLeft, lastX = -1, lastY = -1; 79912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn int i = 0; 80012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn Path curLevelPath = null; 80112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn Path lastLinePath = null; 802cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn boolean lastCharging = false, lastScreenOn = false, lastGpsOn = false; 80396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn boolean lastWifiRunning = false, lastWifiSupplRunning = false, lastCpuRunning = false; 80496debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn int lastWifiSupplState = BatteryStats.WIFI_SUPPL_STATE_INVALID; 805ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn final int N = mNumHist; 8062b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (mEndDataWallTime > mStartWallTime && mStats.startIteratingHistoryLocked()) { 80719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn final HistoryItem rec = new HistoryItem(); 80819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn while (mStats.getNextHistoryLocked(rec) && i < N) { 8092b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (rec.isDeltaData()) { 8105a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn curWalltime += rec.time-lastRealtime; 8115a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastRealtime = rec.time; 8125a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn x = mLevelLeft + (int)(((curWalltime-walltimeStart)*levelWidth)/walltimeChange); 8131cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn if (x < 0) { 8141cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn x = 0; 8151cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn } 8165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (false) { 8175a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn StringBuilder sb = new StringBuilder(128); 8185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn sb.append("walloff="); 8195a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn TimeUtils.formatDuration(curWalltime - walltimeStart, sb); 8205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn sb.append(" wallchange="); 8215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn TimeUtils.formatDuration(walltimeChange, sb); 8225a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn sb.append(" x="); 8235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn sb.append(x); 8245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn Log.d("foo", sb.toString()); 8255a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 82619df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange; 82719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 82819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (lastX != x) { 82919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn // We have moved by at least a pixel. 83019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (lastY != y) { 83119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn // Don't plot changes within a pixel. 83219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn Path path; 83319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn byte value = rec.batteryLevel; 8347158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (value <= mBatteryCriticalLevel) path = mBatCriticalPath; 8357158e6299210d08f82c29135c001652508b79dfbDianne Hackborn else if (value <= mBatteryWarnLevel) path = mBatWarnPath; 8367158e6299210d08f82c29135c001652508b79dfbDianne Hackborn else path = null; //mBatGoodPath; 83719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 83819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (path != lastLinePath) { 83919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (lastLinePath != null) { 84019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastLinePath.lineTo(x, y); 84119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 8427158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (path != null) { 8437158e6299210d08f82c29135c001652508b79dfbDianne Hackborn path.moveTo(x, y); 8447158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 84519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastLinePath = path; 8467158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else if (path != null) { 84719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn path.lineTo(x, y); 84819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } 84919df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 85019df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn if (curLevelPath == null) { 85119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn curLevelPath = mBatLevelPath; 85219df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn curLevelPath.moveTo(x, y); 85319df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn startX = x; 85419df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn } else { 85519df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn curLevelPath.lineTo(x, y); 85612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 85719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastX = x; 85819df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn lastY = y; 85912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 86056247a63fc621815ecff82a278ad8553174922a0Todd Poynor } 86119df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn 8625a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mLargeMode) { 8635a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final boolean charging = 8645a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn (rec.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0; 8655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (charging != lastCharging) { 8665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (charging) { 8675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargingPath.moveTo(x, h-mChargingOffset); 8685a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 8695a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mChargingPath.lineTo(x, h-mChargingOffset); 8705a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 8715a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastCharging = charging; 87212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 873cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 8745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final boolean screenOn = 8755a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn (rec.states&HistoryItem.STATE_SCREEN_ON_FLAG) != 0; 8765a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (screenOn != lastScreenOn) { 8775a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (screenOn) { 8785a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mScreenOnPath.moveTo(x, h-mScreenOnOffset); 8795a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 8805a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mScreenOnPath.lineTo(x, h-mScreenOnOffset); 8815a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 8825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastScreenOn = screenOn; 88312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 884cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 8855a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final boolean gpsOn = 8865a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn (rec.states&HistoryItem.STATE_GPS_ON_FLAG) != 0; 8875a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (gpsOn != lastGpsOn) { 8885a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (gpsOn) { 8895a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mGpsOnPath.moveTo(x, h-mGpsOnOffset); 8905a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 8915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mGpsOnPath.lineTo(x, h-mGpsOnOffset); 8925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 8935a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastGpsOn = gpsOn; 894cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 895cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 89696debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn final int wifiSupplState = 89796debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn ((rec.states2&HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 89896debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn >> HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 89996debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn boolean wifiRunning; 90096debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn if (lastWifiSupplState != wifiSupplState) { 90196debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn lastWifiSupplState = wifiSupplState; 90296debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn switch (wifiSupplState) { 90396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_DISCONNECTED: 90496debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_DORMANT: 90596debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_INACTIVE: 90696debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_INTERFACE_DISABLED: 90796debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_INVALID: 90896debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn case BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED: 90996debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn wifiRunning = lastWifiSupplRunning = false; 91096debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn break; 91196debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn default: 91296debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn wifiRunning = lastWifiSupplRunning = true; 91396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn break; 91496debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn } 91596debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn } else { 91696debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn wifiRunning = lastWifiSupplRunning; 91796debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn } 91896debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn if ((rec.states&(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG 91996debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn |HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG 92096debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn |HistoryItem.STATE_WIFI_SCAN_FLAG)) != 0) { 92196debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn wifiRunning = true; 92296debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn } 9235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (wifiRunning != lastWifiRunning) { 9245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (wifiRunning) { 9255a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mWifiRunningPath.moveTo(x, h-mWifiRunningOffset); 9265a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 9275a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mWifiRunningPath.lineTo(x, h-mWifiRunningOffset); 9285a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 9295a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastWifiRunning = wifiRunning; 930cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 931cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 9325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final boolean cpuRunning = 9335a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn (rec.states&HistoryItem.STATE_CPU_RUNNING_FLAG) != 0; 9345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (cpuRunning != lastCpuRunning) { 9355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (cpuRunning) { 9365a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mCpuRunningPath.moveTo(x, h - mCpuRunningOffset); 9375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 9385a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mCpuRunningPath.lineTo(x, h - mCpuRunningOffset); 9395a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 9405a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastCpuRunning = cpuRunning; 941be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 942be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn 9435a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mLargeMode && mHavePhoneSignal) { 9445a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int bin; 9455a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (((rec.states&HistoryItem.STATE_PHONE_STATE_MASK) 9465a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn >> HistoryItem.STATE_PHONE_STATE_SHIFT) 9475a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn == ServiceState.STATE_POWER_OFF) { 9485a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn bin = 0; 9495a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else if ((rec.states&HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) { 9505a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn bin = 1; 9515a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 95296debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn bin = (rec.states&HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 95396debb5c96e8b75945ea2c2e1171cf29fe2c2887Dianne Hackborn >> HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT; 9545a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn bin += 2; 9555a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 9565a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mPhoneSignalChart.addTick(x, bin); 957be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 958be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 959be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn 9602b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } else { 9612b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn long lastWalltime = curWalltime; 9622b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (rec.cmd == HistoryItem.CMD_CURRENT_TIME 9632b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn || rec.cmd == HistoryItem.CMD_RESET) { 9642b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (rec.currentTime >= mStartWallTime) { 9652b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn curWalltime = rec.currentTime; 9662b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } else { 9672b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn curWalltime = mStartWallTime + (rec.time-mHistStart); 9682b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } 9692b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastRealtime = rec.time; 9702b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } 9712b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn 9722b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (rec.cmd != HistoryItem.CMD_OVERFLOW 9732b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn && (rec.cmd != HistoryItem.CMD_CURRENT_TIME 9742b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn || Math.abs(lastWalltime-curWalltime) > (60*60*1000))) { 9752b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn if (curLevelPath != null) { 9762b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX, 9772b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, 9782b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastCpuRunning, lastLinePath); 9792b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastX = lastY = -1; 9802b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn curLevelPath = null; 9812b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastLinePath = null; 9822b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn lastCharging = lastScreenOn = lastGpsOn = lastCpuRunning = false; 9832b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn } 9844f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn } 9854f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn } 98612fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn 98719df79af269c4a2354b0989cebfcfe949aea42c4Dianne Hackborn i++; 988ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 9892b54a9fa571a429e188b5e37d4732debd3e90ac0Dianne Hackborn mStats.finishIteratingHistoryLocked(); 990ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 9915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 992c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn if (lastY < 0 || lastX < 0) { 993c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn // Didn't get any data... 994c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn x = lastX = mLevelLeft; 995c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn y = lastY = mLevelTop + levelh - ((mBatteryLevel-batLow)*(levelh-1))/batChange; 996c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn Path path; 997c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn byte value = (byte)mBatteryLevel; 998c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn if (value <= mBatteryCriticalLevel) path = mBatCriticalPath; 999c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn else if (value <= mBatteryWarnLevel) path = mBatWarnPath; 1000c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn else path = null; //mBatGoodPath; 1001c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn if (path != null) { 1002c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn path.moveTo(x, y); 1003c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn lastLinePath = path; 1004c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn } 1005c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn mBatLevelPath.moveTo(x, y); 1006c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn curLevelPath = mBatLevelPath; 1007c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn x = w; 1008c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn } else { 1009c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn // Figure out where the actual data ends on the screen. 1010c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn x = mLevelLeft + (int)(((mEndDataWallTime-walltimeStart)*levelWidth)/walltimeChange); 10111cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn if (x < 0) { 10121cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn x = 0; 10131cf2077c3762349f4838ab041e6a06363ebd0b26Dianne Hackborn } 1014c19eb361a407058b76cbbc866106db9fc81d9596Dianne Hackborn } 10155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 10165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn finishPaths(x, h, levelh, startX, lastY, curLevelPath, lastX, 1017be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, 101855985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn lastCpuRunning, lastLinePath); 10195a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 10205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (x < w) { 10215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // If we reserved room for the remaining time, create a final path to draw 10225a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // that part of the UI. 10235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.moveTo(x, lastY); 10245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int fullY = mLevelTop + levelh - ((100-batLow)*(levelh-1))/batChange; 10255a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int emptyY = mLevelTop + levelh - ((0-batLow)*(levelh-1))/batChange; 10265a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mDischarging) { 10275a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.lineTo(mLevelRight, emptyY); 10285a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 10295a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.lineTo(mLevelRight, fullY); 10305a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.lineTo(mLevelRight, emptyY); 10315a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 10325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.lineTo(x, emptyY); 10335a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTimeRemainPath.close(); 10345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 10355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 1036c891ce6565fbeba8414c470b109088ac959f7143Dianne Hackborn if (mStartWallTime > 0 && mEndWallTime > mStartWallTime) { 10377158e6299210d08f82c29135c001652508b79dfbDianne Hackborn // Create the time labels at the bottom. 10387158e6299210d08f82c29135c001652508b79dfbDianne Hackborn boolean is24hr = is24Hour(); 10397158e6299210d08f82c29135c001652508b79dfbDianne Hackborn Calendar calStart = Calendar.getInstance(); 10407158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.setTimeInMillis(mStartWallTime); 10417158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.MILLISECOND, 0); 10427158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.SECOND, 0); 10437158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.MINUTE, 0); 10447158e6299210d08f82c29135c001652508b79dfbDianne Hackborn long startRoundTime = calStart.getTimeInMillis(); 10455a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (startRoundTime < mStartWallTime) { 10467158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.HOUR_OF_DAY, calStart.get(Calendar.HOUR_OF_DAY)+1); 10475a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn startRoundTime = calStart.getTimeInMillis(); 10485a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 10497158e6299210d08f82c29135c001652508b79dfbDianne Hackborn Calendar calEnd = Calendar.getInstance(); 10507158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calEnd.setTimeInMillis(mEndWallTime); 10517158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calEnd.set(Calendar.MILLISECOND, 0); 10527158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calEnd.set(Calendar.SECOND, 0); 10537158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calEnd.set(Calendar.MINUTE, 0); 10547158e6299210d08f82c29135c001652508b79dfbDianne Hackborn long endRoundTime = calEnd.getTimeInMillis(); 10555a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (startRoundTime < endRoundTime) { 10567158e6299210d08f82c29135c001652508b79dfbDianne Hackborn addTimeLabel(calStart, mLevelLeft, mLevelRight, is24hr); 10577158e6299210d08f82c29135c001652508b79dfbDianne Hackborn Calendar calMid = Calendar.getInstance(); 10587158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calMid.setTimeInMillis(mStartWallTime+((mEndWallTime-mStartWallTime)/2)); 10597158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calMid.set(Calendar.MILLISECOND, 0); 10607158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calMid.set(Calendar.SECOND, 0); 10617158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calMid.set(Calendar.MINUTE, 0); 10627158e6299210d08f82c29135c001652508b79dfbDianne Hackborn long calMidMillis = calMid.getTimeInMillis(); 10637158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (calMidMillis > startRoundTime && calMidMillis < endRoundTime) { 10647158e6299210d08f82c29135c001652508b79dfbDianne Hackborn addTimeLabel(calMid, mLevelLeft, mLevelRight, is24hr); 10657158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 10667158e6299210d08f82c29135c001652508b79dfbDianne Hackborn addTimeLabel(calEnd, mLevelLeft, mLevelRight, is24hr); 10677158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 10687158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 10697158e6299210d08f82c29135c001652508b79dfbDianne Hackborn // Create the date labels if the chart includes multiple days 10707158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (calStart.get(Calendar.DAY_OF_YEAR) != calEnd.get(Calendar.DAY_OF_YEAR) || 10717158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.get(Calendar.YEAR) != calEnd.get(Calendar.YEAR)) { 10727158e6299210d08f82c29135c001652508b79dfbDianne Hackborn boolean isDayFirst = isDayFirst(); 10737158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.HOUR_OF_DAY, 0); 10747158e6299210d08f82c29135c001652508b79dfbDianne Hackborn startRoundTime = calStart.getTimeInMillis(); 10757158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (startRoundTime < mStartWallTime) { 10767158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calStart.set(Calendar.DAY_OF_YEAR, calStart.get(Calendar.DAY_OF_YEAR) + 1); 10777158e6299210d08f82c29135c001652508b79dfbDianne Hackborn startRoundTime = calStart.getTimeInMillis(); 10787158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 10797158e6299210d08f82c29135c001652508b79dfbDianne Hackborn calEnd.set(Calendar.HOUR_OF_DAY, 0); 10807158e6299210d08f82c29135c001652508b79dfbDianne Hackborn endRoundTime = calEnd.getTimeInMillis(); 10817158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (startRoundTime < endRoundTime) { 10827158e6299210d08f82c29135c001652508b79dfbDianne Hackborn addDateLabel(calStart, mLevelLeft, mLevelRight, isDayFirst); 10836fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn Calendar calMid = Calendar.getInstance(); 10846fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn calMid.setTimeInMillis(startRoundTime + ((endRoundTime - startRoundTime) / 2)); 10856fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn calMid.set(Calendar.HOUR_OF_DAY, 0); 10866fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn long calMidMillis = calMid.getTimeInMillis(); 10876fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (calMidMillis > startRoundTime && calMidMillis < endRoundTime) { 10886fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn addDateLabel(calMid, mLevelLeft, mLevelRight, isDayFirst); 10896fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn } 10907158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 10917158e6299210d08f82c29135c001652508b79dfbDianne Hackborn addDateLabel(calEnd, mLevelLeft, mLevelRight, isDayFirst); 10925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 10937158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } 10947158e6299210d08f82c29135c001652508b79dfbDianne Hackborn 10957158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (mTimeLabels.size() < 2) { 10967158e6299210d08f82c29135c001652508b79dfbDianne Hackborn // If there are fewer than 2 time labels, then they are useless. Just 10977158e6299210d08f82c29135c001652508b79dfbDianne Hackborn // show an axis label giving the entire duration. 10987158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mDurationString = Formatter.formatShortElapsedTime(getContext(), 10997158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mEndWallTime - mStartWallTime); 11007158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mDurationStringWidth = (int)mTextPaint.measureText(mDurationString); 11017158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else { 11027158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mDurationString = null; 11037158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mDurationStringWidth = 0; 11045a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11054f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn } 11065a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11075a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn void addTimeLabel(Calendar cal, int levelLeft, int levelRight, boolean is24hr) { 11085a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long walltimeStart = mStartWallTime; 11095a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long walltimeChange = mEndWallTime-walltimeStart; 1110a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio mTimeLabels.add(new TimeLabel(mTextPaint, 11115a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft)) 11125a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn / walltimeChange), 11135a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn cal, is24hr)); 11145a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn void addDateLabel(Calendar cal, int levelLeft, int levelRight, boolean isDayFirst) { 11175a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long walltimeStart = mStartWallTime; 11185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn final long walltimeChange = mEndWallTime-walltimeStart; 1119a7a62c5b66189f114a8ad41c53bbe0bb00ae1e90Fabrice Di Meglio mDateLabels.add(new DateLabel(mTextPaint, 11205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft)) 11215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn / walltimeChange), 11225a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn cal, isDayFirst)); 11235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11254f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn @Override 11264f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn protected void onDraw(Canvas canvas) { 11274f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn super.onDraw(canvas); 112874809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani 11294f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final int width = getWidth(); 11304f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn final int height = getHeight(); 11315a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11326fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn //buildBitmap(width, height); 11336fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 11345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "onDraw: " + width + "x" + height); 11356fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn //canvas.drawBitmap(mBitmap, 0, 0, null); 11366fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn drawChart(canvas, width, height); 11376fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn } 11386fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 11396fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn void buildBitmap(int width, int height) { 11406fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (mBitmap != null && width == mBitmap.getWidth() && height == mBitmap.getHeight()) { 11416fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn return; 11426fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn } 11436fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 11446fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn if (DEBUG) Log.d(TAG, "buildBitmap: " + width + "x" + height); 11456fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn 11466fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn mBitmap = Bitmap.createBitmap(getResources().getDisplayMetrics(), width, height, 11476fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn Bitmap.Config.ARGB_8888); 11486fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn mCanvas = new Canvas(mBitmap); 11496fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn drawChart(mCanvas, width, height); 11506fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn } 11515a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11526fd48e224f89e4d4e154dcf2e494c201293cc167Dianne Hackborn void drawChart(Canvas canvas, int width, int height) { 115374809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani final boolean layoutRtl = isLayoutRtl(); 115474809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani final int textStartX = layoutRtl ? width : 0; 11550be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final int textEndX = layoutRtl ? 0 : width; 11560be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final Paint.Align textAlignLeft = layoutRtl ? Paint.Align.RIGHT : Paint.Align.LEFT; 11570be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn final Paint.Align textAlignRight = layoutRtl ? Paint.Align.LEFT : Paint.Align.RIGHT; 115874809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani 11595a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) { 11605a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawRect(1, 1, width, height, mDebugRectPaint); 11615a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11625a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 11635a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing level path."); 11644f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn canvas.drawPath(mBatLevelPath, mBatteryBackgroundPaint); 11655a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (!mTimeRemainPath.isEmpty()) { 11665a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing time remain path."); 11675a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawPath(mTimeRemainPath, mTimeRemainPaint); 11685a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11697158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (mTimeLabels.size() > 1) { 11705a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int y = mLevelBottom - mTextAscent + (mThinLineWidth*4); 11715a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int ytick = mLevelBottom+mThinLineWidth+(mThinLineWidth/2); 11725a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTextPaint.setTextAlign(Paint.Align.LEFT); 11735a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int lastX = 0; 11745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn for (int i=0; i<mTimeLabels.size(); i++) { 11755a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn TimeLabel label = mTimeLabels.get(i); 11765a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (i == 0) { 11775a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int x = label.x - label.width/2; 11785a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (x < 0) { 11795a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn x = 0; 11805a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11815a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing left label: " + label.label + " @ " + x); 11825a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(label.label, x, y, mTextPaint); 11835a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint); 11845a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastX = x + label.width; 11855a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else if (i < (mTimeLabels.size()-1)) { 11865a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int x = label.x - label.width/2; 11875a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (x < (lastX+mTextAscent)) { 11885a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn continue; 11895a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11905a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn TimeLabel nextLabel = mTimeLabels.get(i+1); 11915a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (x > (width-nextLabel.width-mTextAscent)) { 11925a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn continue; 11935a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 11945a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing middle label: " + label.label + " @ " + x); 11955a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(label.label, x, y, mTextPaint); 11965a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawLine(label.x, ytick, label.x, ytick + mThinLineWidth, mTextPaint); 11975a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn lastX = x + label.width; 11985a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } else { 11995a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int x = label.x - label.width/2; 12005a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if ((x+label.width) >= width) { 12015a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn x = width-1-label.width; 12025a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 12035a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing right label: " + label.label + " @ " + x); 12045a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(label.label, x, y, mTextPaint); 12055a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint); 12065a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 12075a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 12087158e6299210d08f82c29135c001652508b79dfbDianne Hackborn } else if (mDurationString != null) { 12097158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int y = mLevelBottom - mTextAscent + (mThinLineWidth*4); 12107158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mTextPaint.setTextAlign(Paint.Align.LEFT); 12117158e6299210d08f82c29135c001652508b79dfbDianne Hackborn canvas.drawText(mDurationString, 12127158e6299210d08f82c29135c001652508b79dfbDianne Hackborn mLevelLeft + (mLevelRight-mLevelLeft)/2 - mDurationStringWidth/2, 12137158e6299210d08f82c29135c001652508b79dfbDianne Hackborn y, mTextPaint); 12145a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 12155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 12165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int headerTop = -mHeaderTextAscent + (mHeaderTextDescent-mHeaderTextAscent)/3; 12170be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextPaint.setTextAlign(textAlignLeft); 12185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing charge label string: " + mChargeLabelString); 12190be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn canvas.drawText(mChargeLabelString, textStartX, headerTop, mHeaderTextPaint); 12207158e6299210d08f82c29135c001652508b79dfbDianne Hackborn int stringHalfWidth = mChargeDurationStringWidth / 2; 12217158e6299210d08f82c29135c001652508b79dfbDianne Hackborn if (layoutRtl) stringHalfWidth = -stringHalfWidth; 12220be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn int headerCenter = ((width-mChargeDurationStringWidth-mDrainStringWidth)/2) 12230be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn + (layoutRtl ? mDrainStringWidth : mChargeLabelStringWidth); 12245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing charge duration string: " + mChargeDurationString); 12257158e6299210d08f82c29135c001652508b79dfbDianne Hackborn canvas.drawText(mChargeDurationString, headerCenter - stringHalfWidth, headerTop, 12260be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextPaint); 12270be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn mHeaderTextPaint.setTextAlign(textAlignRight); 12285a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing drain string: " + mDrainString); 12290be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn canvas.drawText(mDrainString, textEndX, headerTop, mHeaderTextPaint); 12300be7598cb8c8cf6808b336204632615c5f26298fDianne Hackborn 123112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (!mBatGoodPath.isEmpty()) { 12325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing good battery path"); 123312fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn canvas.drawPath(mBatGoodPath, mBatteryGoodPaint); 123412fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 123512fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (!mBatWarnPath.isEmpty()) { 12365a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing warn battery path"); 123712fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn canvas.drawPath(mBatWarnPath, mBatteryWarnPaint); 123812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 123912fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (!mBatCriticalPath.isEmpty()) { 12405a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing critical battery path"); 124112fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint); 124212fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn } 1243c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani if (mHavePhoneSignal) { 12445a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing phone signal path"); 1245b28c0c95c21bb60b8259b0cafb16754e590b4a9bDianne Hackborn int top = height-mPhoneSignalOffset - (mLineWidth/2); 1246c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani mPhoneSignalChart.draw(canvas, top, mLineWidth); 1247c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 124812fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn if (!mScreenOnPath.isEmpty()) { 12495a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing screen on path"); 125012fd447d6f46b0c06072b0e9735589bf14cc53f6Dianne Hackborn canvas.drawPath(mScreenOnPath, mScreenOnPaint); 12514f0e5350fccd78bf881b938aaf0f484d135829a0Dianne Hackborn } 1252cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (!mChargingPath.isEmpty()) { 12535a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing charging path"); 1254cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn canvas.drawPath(mChargingPath, mChargingPaint); 1255cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 1256be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (mHaveGps) { 1257be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (!mGpsOnPath.isEmpty()) { 12585a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing gps path"); 1259be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn canvas.drawPath(mGpsOnPath, mGpsOnPaint); 1260be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 1261be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 1262be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (mHaveWifi) { 1263be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (!mWifiRunningPath.isEmpty()) { 12645a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing wifi path"); 1265be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn canvas.drawPath(mWifiRunningPath, mWifiRunningPaint); 1266be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 1267be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 126855985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn if (!mCpuRunningPath.isEmpty()) { 12695a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing running path"); 127055985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn canvas.drawPath(mCpuRunningPath, mCpuRunningPaint); 1271cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 1272cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn 1273cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn if (mLargeMode) { 12745a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing large mode labels"); 1275a312f7f8044a07a2a41de477cc30bb34fc1df55fJohn Spurlock Paint.Align align = mTextPaint.getTextAlign(); 1276a312f7f8044a07a2a41de477cc30bb34fc1df55fJohn Spurlock mTextPaint.setTextAlign(textAlignLeft); // large-mode labels always aligned to start 1277c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani if (mHavePhoneSignal) { 127874809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani canvas.drawText(mPhoneSignalLabel, textStartX, 1279c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani height - mPhoneSignalOffset - mTextDescent, mTextPaint); 1280c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani } 1281be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (mHaveGps) { 128274809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani canvas.drawText(mGpsOnLabel, textStartX, 1283be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn height - mGpsOnOffset - mTextDescent, mTextPaint); 1284be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 1285be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn if (mHaveWifi) { 128674809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani canvas.drawText(mWifiRunningLabel, textStartX, 1287be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn height - mWifiRunningOffset - mTextDescent, mTextPaint); 1288be5994d20152c7194aac79eb8152240655fd3373Dianne Hackborn } 128955985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn canvas.drawText(mCpuRunningLabel, textStartX, 129055985d2ceca9cecfbc07bb331bf48fe28849b818Dianne Hackborn height - mCpuRunningOffset - mTextDescent, mTextPaint); 129174809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani canvas.drawText(mChargingLabel, textStartX, 1292cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn height - mChargingOffset - mTextDescent, mTextPaint); 129374809c2679d9c046f73acb4473434f9f5ad4b1c1Amith Yamasani canvas.drawText(mScreenOnLabel, textStartX, 1294cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn height - mScreenOnOffset - mTextDescent, mTextPaint); 1295a312f7f8044a07a2a41de477cc30bb34fc1df55fJohn Spurlock mTextPaint.setTextAlign(align); 12965a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 12975a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 12985a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawLine(mLevelLeft-mThinLineWidth, mLevelTop, mLevelLeft-mThinLineWidth, 12995a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelBottom+(mThinLineWidth/2), mTextPaint); 13005a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mLargeMode) { 1301cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn for (int i=0; i<10; i++) { 13025a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int y = mLevelTop + mThinLineWidth/2 + ((mLevelBottom-mLevelTop)*i)/10; 13035a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawLine(mLevelLeft-mThinLineWidth*2-mThinLineWidth/2, y, 13045a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelLeft-mThinLineWidth-mThinLineWidth/2, y, mTextPaint); 13055a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 13065a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 13075a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (DEBUG) Log.d(TAG, "Drawing max percent, origw=" + mMaxPercentLabelStringWidth 13085a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn + ", noww=" + (int)mTextPaint.measureText(mMaxPercentLabelString)); 13095a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(mMaxPercentLabelString, 0, mLevelTop, mTextPaint); 13105a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(mMinPercentLabelString, 13115a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mMaxPercentLabelStringWidth-mMinPercentLabelStringWidth, 13125a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelBottom - mThinLineWidth, mTextPaint); 13137158e6299210d08f82c29135c001652508b79dfbDianne Hackborn canvas.drawLine(mLevelLeft/2, mLevelBottom+mThinLineWidth, width, 13145a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mLevelBottom+mThinLineWidth, mTextPaint); 13155a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn 13165a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (mDateLabels.size() > 0) { 13175a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int ytop = mLevelTop + mTextAscent; 13185a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int ybottom = mLevelBottom; 13195a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int lastLeft = mLevelRight; 13205a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mTextPaint.setTextAlign(Paint.Align.LEFT); 13215a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn for (int i=mDateLabels.size()-1; i>=0; i--) { 13225a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn DateLabel label = mDateLabels.get(i); 13235a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int left = label.x - mThinLineWidth; 13245a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn int x = label.x + mThinLineWidth*2; 13255a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if ((x+label.width) >= lastLeft) { 13265a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn x = label.x - mThinLineWidth*2 - label.width; 13275a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn left = x - mThinLineWidth; 13285a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (left >= lastLeft) { 13295a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // okay we give up. 13305a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn continue; 13315a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 13325a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 13335a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn if (left < mLevelLeft) { 13345a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn // Won't fit on left, give up. 13355a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn continue; 13365a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn } 13375a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePath.reset(); 13385a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePath.moveTo(label.x, ytop); 13395a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn mDateLinePath.lineTo(label.x, ybottom); 13405a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawPath(mDateLinePath, mDateLinePaint); 13415a9ace3a7abe5de8d6f3307dad830ac9b1d5ae04Dianne Hackborn canvas.drawText(label.label, x, ytop - mTextAscent, mTextPaint); 1342cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 1343cbaf6ceb8e6b2d36a40589de6380ff93e75335dfDianne Hackborn } 1344ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn } 1345ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn} 1346