void setStats(BatteryStats stats) { mStats = stats; long uSecTime = mStats.computeBatteryRealtime( SystemClock.elapsedRealtime() * 1000, BatteryStats.STATS_SINCE_CHARGED); mStatsPeriod = uSecTime; String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000); mDurationString = getContext().getString(R.string.battery_stats_on_battery, durationString); mChargingLabel = getContext().getString(R.string.battery_stats_charging_label); mScreenOnLabel = getContext().getString(R.string.battery_stats_screen_on_label); mGpsOnLabel = getContext().getString(R.string.battery_stats_gps_on_label); mWifiRunningLabel = getContext().getString(R.string.battery_stats_wifi_running_label); mWakeLockLabel = getContext().getString(R.string.battery_stats_wake_lock_label); mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label); int pos = 0; int lastInteresting = 0; byte lastLevel = -1; mBatLow = 0; mBatHigh = 100; int aggrStates = 0; boolean first = true; if (stats.startIteratingHistoryLocked()) { final HistoryItem rec = new HistoryItem(); while (stats.getNextHistoryLocked(rec)) { pos++; if (rec.cmd == HistoryItem.CMD_UPDATE) { if (first) { first = false; mHistStart = rec.time; } if (rec.batteryLevel != lastLevel || pos == 1) { lastLevel = rec.batteryLevel; lastInteresting = pos; mHistEnd = rec.time; } aggrStates |= rec.states; } } } mNumHist = lastInteresting; mHaveGps = (aggrStates & HistoryItem.STATE_GPS_ON_FLAG) != 0; mHaveWifi = (aggrStates & HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0; if (mHistEnd <= mHistStart) mHistEnd = mHistStart + 1; mTotalDurationString = Utils.formatElapsedTime(getContext(), mHistEnd - mHistStart); }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int textHeight = mTextDescent - mTextAscent; mThinLineWidth = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics()); if (h > (textHeight * 6)) { mLargeMode = true; mLineWidth = textHeight / 2; mLevelTop = textHeight + mLineWidth; mScreenOnPaint.setARGB(255, 32, 64, 255); mGpsOnPaint.setARGB(255, 32, 64, 255); mWifiRunningPaint.setARGB(255, 32, 64, 255); mWakeLockPaint.setARGB(255, 32, 64, 255); } else { mLargeMode = false; mLineWidth = mThinLineWidth; mLevelTop = 0; mScreenOnPaint.setARGB(255, 0, 0, 255); mGpsOnPaint.setARGB(255, 0, 0, 255); mWifiRunningPaint.setARGB(255, 0, 0, 255); mWakeLockPaint.setARGB(255, 0, 0, 255); } if (mLineWidth <= 0) mLineWidth = 1; mTextPaint.setStrokeWidth(mThinLineWidth); mBatteryGoodPaint.setStrokeWidth(mThinLineWidth); mBatteryWarnPaint.setStrokeWidth(mThinLineWidth); mBatteryCriticalPaint.setStrokeWidth(mThinLineWidth); mChargingPaint.setStrokeWidth(mLineWidth); mScreenOnPaint.setStrokeWidth(mLineWidth); mGpsOnPaint.setStrokeWidth(mLineWidth); mWifiRunningPaint.setStrokeWidth(mLineWidth); mWakeLockPaint.setStrokeWidth(mLineWidth); if (mLargeMode) { int barOffset = textHeight + mLineWidth; mChargingOffset = mLineWidth; mScreenOnOffset = mChargingOffset + barOffset; mWakeLockOffset = mScreenOnOffset + barOffset; mWifiRunningOffset = mWakeLockOffset + barOffset; mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? barOffset : 0); mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? barOffset : 0); mLevelOffset = mPhoneSignalOffset + barOffset + mLineWidth; mPhoneSignalChart.init(w); } else { mScreenOnOffset = mGpsOnOffset = mWifiRunningOffset = mWakeLockOffset = mLineWidth; mChargingOffset = mLineWidth * 2; mPhoneSignalOffset = 0; mLevelOffset = mLineWidth * 3; mPhoneSignalChart.init(0); } mBatLevelPath.reset(); mBatGoodPath.reset(); mBatWarnPath.reset(); mBatCriticalPath.reset(); mScreenOnPath.reset(); mGpsOnPath.reset(); mWifiRunningPath.reset(); mWakeLockPath.reset(); mChargingPath.reset(); final long timeStart = mHistStart; final long timeChange = mHistEnd - mHistStart; final int batLow = mBatLow; final int batChange = mBatHigh - mBatLow; final int levelh = h - mLevelOffset - mLevelTop; mLevelBottom = mLevelTop + levelh; int x = 0, y = 0, startX = 0, lastX = -1, lastY = -1; int i = 0; Path curLevelPath = null; Path lastLinePath = null; boolean lastCharging = false, lastScreenOn = false, lastGpsOn = false; boolean lastWifiRunning = false, lastWakeLock = false; final int N = mNumHist; if (mStats.startIteratingHistoryLocked()) { final HistoryItem rec = new HistoryItem(); while (mStats.getNextHistoryLocked(rec) && i < N) { if (rec.cmd == BatteryStats.HistoryItem.CMD_UPDATE) { x = (int) (((rec.time - timeStart) * w) / timeChange); y = mLevelTop + levelh - ((rec.batteryLevel - batLow) * (levelh - 1)) / batChange; if (lastX != x) { // We have moved by at least a pixel. if (lastY != y) { // Don't plot changes within a pixel. Path path; byte value = rec.batteryLevel; if (value <= BATTERY_CRITICAL) path = mBatCriticalPath; else if (value <= BATTERY_WARN) path = mBatWarnPath; else path = mBatGoodPath; if (path != lastLinePath) { if (lastLinePath != null) { lastLinePath.lineTo(x, y); } path.moveTo(x, y); lastLinePath = path; } else { path.lineTo(x, y); } if (curLevelPath == null) { curLevelPath = mBatLevelPath; curLevelPath.moveTo(x, y); startX = x; } else { curLevelPath.lineTo(x, y); } lastX = x; lastY = y; } final boolean charging = (rec.states & HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0; if (charging != lastCharging) { if (charging) { mChargingPath.moveTo(x, h - mChargingOffset); } else { mChargingPath.lineTo(x, h - mChargingOffset); } lastCharging = charging; } final boolean screenOn = (rec.states & HistoryItem.STATE_SCREEN_ON_FLAG) != 0; if (screenOn != lastScreenOn) { if (screenOn) { mScreenOnPath.moveTo(x, h - mScreenOnOffset); } else { mScreenOnPath.lineTo(x, h - mScreenOnOffset); } lastScreenOn = screenOn; } final boolean gpsOn = (rec.states & HistoryItem.STATE_GPS_ON_FLAG) != 0; if (gpsOn != lastGpsOn) { if (gpsOn) { mGpsOnPath.moveTo(x, h - mGpsOnOffset); } else { mGpsOnPath.lineTo(x, h - mGpsOnOffset); } lastGpsOn = gpsOn; } final boolean wifiRunning = (rec.states & HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0; if (wifiRunning != lastWifiRunning) { if (wifiRunning) { mWifiRunningPath.moveTo(x, h - mWifiRunningOffset); } else { mWifiRunningPath.lineTo(x, h - mWifiRunningOffset); } lastWifiRunning = wifiRunning; } final boolean wakeLock = (rec.states & HistoryItem.STATE_WAKE_LOCK_FLAG) != 0; if (wakeLock != lastWakeLock) { if (wakeLock) { mWakeLockPath.moveTo(x, h - mWakeLockOffset); } else { mWakeLockPath.lineTo(x, h - mWakeLockOffset); } lastWakeLock = wakeLock; } if (mLargeMode) { int bin; if (((rec.states & HistoryItem.STATE_PHONE_STATE_MASK) >> HistoryItem.STATE_PHONE_STATE_SHIFT) == ServiceState.STATE_POWER_OFF) { bin = 0; } else if ((rec.states & HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) { bin = 1; } else { bin = (rec.states & HistoryItem.STATE_SIGNAL_STRENGTH_MASK) >> HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT; bin += 2; } mPhoneSignalChart.addTick(x, bin); } } } else if (rec.cmd != BatteryStats.HistoryItem.CMD_OVERFLOW) { if (curLevelPath != null) { finishPaths( x + 1, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, lastWakeLock, lastLinePath); lastX = lastY = -1; curLevelPath = null; lastLinePath = null; lastCharging = lastScreenOn = lastGpsOn = lastWakeLock = false; } } i++; } } finishPaths( w, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, lastWakeLock, lastLinePath); }