diff options
Diffstat (limited to 'src/com/android/settings/fuelgauge/BatteryStatsHelper.java')
-rw-r--r-- | src/com/android/settings/fuelgauge/BatteryStatsHelper.java | 836 |
1 files changed, 0 insertions, 836 deletions
diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java deleted file mode 100644 index 0191692a1..000000000 --- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge; - -import static android.os.BatteryStats.NETWORK_MOBILE_RX_BYTES; -import static android.os.BatteryStats.NETWORK_MOBILE_TX_BYTES; -import static android.os.BatteryStats.NETWORK_WIFI_RX_BYTES; -import static android.os.BatteryStats.NETWORK_WIFI_TX_BYTES; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.UserInfo; -import android.graphics.drawable.Drawable; -import android.hardware.Sensor; -import android.hardware.SensorManager; -import android.os.BatteryStats; -import android.os.BatteryStats.Uid; -import android.os.Bundle; -import android.os.Handler; -import android.os.Parcel; -import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.os.UserHandle; -import android.os.UserManager; -import android.preference.PreferenceActivity; -import android.telephony.SignalStrength; -import android.util.Log; -import android.util.SparseArray; - -import com.android.internal.app.IBatteryStats; -import com.android.internal.os.BatteryStatsImpl; -import com.android.internal.os.PowerProfile; -import com.android.internal.util.FastPrintWriter; -import com.android.settings.R; -import com.android.settings.fuelgauge.PowerUsageDetail.DrainType; -import com.android.settings.users.UserUtils; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * A helper class for retrieving the power usage information for all applications and services. - * - * The caller must initialize this class as soon as activity object is ready to use (for example, in - * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy(). - */ -public class BatteryStatsHelper { - - private static final boolean DEBUG = false; - - private static final String TAG = BatteryStatsHelper.class.getSimpleName(); - - private static BatteryStatsImpl sStatsXfer; - private IBatteryStats mBatteryInfo; - private UserManager mUm; - private BatteryStatsImpl mStats; - private PowerProfile mPowerProfile; - - private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>(); - private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>(); - private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>(); - private final SparseArray<List<BatterySipper>> mUserSippers - = new SparseArray<List<BatterySipper>>(); - private final SparseArray<Double> mUserPower = new SparseArray<Double>(); - - private int mStatsType = BatteryStats.STATS_SINCE_CHARGED; - - private long mStatsPeriod = 0; - private double mMaxPower = 1; - private double mTotalPower; - private double mWifiPower; - private double mBluetoothPower; - - // How much the apps together have left WIFI running. - private long mAppWifiRunning; - - /** Queue for fetching name and icon for an application */ - private ArrayList<BatterySipper> mRequestQueue = new ArrayList<BatterySipper>(); - - private Activity mActivity; - private Handler mHandler; - - private class NameAndIconLoader extends Thread { - private boolean mAbort = false; - - public NameAndIconLoader() { - super("BatteryUsage Icon Loader"); - } - - public void abort() { - mAbort = true; - } - - @Override - public void run() { - while (true) { - BatterySipper bs; - synchronized (mRequestQueue) { - if (mRequestQueue.isEmpty() || mAbort) { - mHandler.sendEmptyMessage(MSG_REPORT_FULLY_DRAWN); - return; - } - bs = mRequestQueue.remove(0); - } - bs.loadNameAndIcon(); - } - } - } - - private NameAndIconLoader mRequestThread; - - public BatteryStatsHelper(Activity activity, Handler handler) { - mActivity = activity; - mHandler = handler; - } - - /** Clears the current stats and forces recreating for future use. */ - public void clearStats() { - mStats = null; - } - - public BatteryStatsImpl getStats() { - if (mStats == null) { - load(); - } - return mStats; - } - - public PowerProfile getPowerProfile() { - return mPowerProfile; - } - - public void create(Bundle icicle) { - if (icicle != null) { - mStats = sStatsXfer; - } - mBatteryInfo = IBatteryStats.Stub.asInterface( - ServiceManager.getService(BatteryStats.SERVICE_NAME)); - mUm = (UserManager) mActivity.getSystemService(Context.USER_SERVICE); - mPowerProfile = new PowerProfile(mActivity); - } - - public void pause() { - if (mRequestThread != null) { - mRequestThread.abort(); - } - } - - public void destroy() { - if (mActivity.isChangingConfigurations()) { - sStatsXfer = mStats; - } else { - BatterySipper.sUidCache.clear(); - } - } - - public void startBatteryDetailPage( - PreferenceActivity caller, BatterySipper sipper, boolean showLocationButton) { - // Initialize mStats if necessary. - getStats(); - - Bundle args = new Bundle(); - args.putString(PowerUsageDetail.EXTRA_TITLE, sipper.name); - args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int) - Math.ceil(sipper.getSortValue() * 100 / mTotalPower)); - args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int) - Math.ceil(sipper.getSortValue() * 100 / mMaxPower)); - args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, mStatsPeriod); - args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, sipper.defaultPackageName); - args.putInt(PowerUsageDetail.EXTRA_ICON_ID, sipper.iconId); - args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, sipper.noCoveragePercent); - if (sipper.uidObj != null) { - args.putInt(PowerUsageDetail.EXTRA_UID, sipper.uidObj.getUid()); - } - args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, sipper.drainType); - args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton); - - int[] types; - double[] values; - switch (sipper.drainType) { - case APP: - case USER: - { - Uid uid = sipper.uidObj; - types = new int[] { - R.string.usage_type_cpu, - R.string.usage_type_cpu_foreground, - R.string.usage_type_wake_lock, - R.string.usage_type_gps, - R.string.usage_type_wifi_running, - R.string.usage_type_data_recv, - R.string.usage_type_data_send, - R.string.usage_type_data_wifi_recv, - R.string.usage_type_data_wifi_send, - R.string.usage_type_audio, - R.string.usage_type_video, - }; - values = new double[] { - sipper.cpuTime, - sipper.cpuFgTime, - sipper.wakeLockTime, - sipper.gpsTime, - sipper.wifiRunningTime, - sipper.mobileRxBytes, - sipper.mobileTxBytes, - sipper.wifiRxBytes, - sipper.wifiTxBytes, - 0, - 0 - }; - - if (sipper.drainType == DrainType.APP) { - Writer result = new StringWriter(); - PrintWriter printWriter = new FastPrintWriter(result, false, 1024); - mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid()); - printWriter.flush(); - args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); - - result = new StringWriter(); - printWriter = new FastPrintWriter(result, false, 1024); - mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid()); - printWriter.flush(); - args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, - result.toString()); - } - } - break; - case CELL: - { - types = new int[] { - R.string.usage_type_on_time, - R.string.usage_type_no_coverage - }; - values = new double[] { - sipper.usageTime, - sipper.noCoveragePercent - }; - } - break; - case WIFI: - { - types = new int[] { - R.string.usage_type_wifi_running, - R.string.usage_type_cpu, - R.string.usage_type_cpu_foreground, - R.string.usage_type_wake_lock, - R.string.usage_type_data_recv, - R.string.usage_type_data_send, - R.string.usage_type_data_wifi_recv, - R.string.usage_type_data_wifi_send, - }; - values = new double[] { - sipper.usageTime, - sipper.cpuTime, - sipper.cpuFgTime, - sipper.wakeLockTime, - sipper.mobileRxBytes, - sipper.mobileTxBytes, - sipper.wifiRxBytes, - sipper.wifiTxBytes, - }; - } break; - case BLUETOOTH: - { - types = new int[] { - R.string.usage_type_on_time, - R.string.usage_type_cpu, - R.string.usage_type_cpu_foreground, - R.string.usage_type_wake_lock, - R.string.usage_type_data_recv, - R.string.usage_type_data_send, - R.string.usage_type_data_wifi_recv, - R.string.usage_type_data_wifi_send, - }; - values = new double[] { - sipper.usageTime, - sipper.cpuTime, - sipper.cpuFgTime, - sipper.wakeLockTime, - sipper.mobileRxBytes, - sipper.mobileTxBytes, - sipper.wifiRxBytes, - sipper.wifiTxBytes, - }; - } break; - default: - { - types = new int[] { - R.string.usage_type_on_time - }; - values = new double[] { - sipper.usageTime - }; - } - } - args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types); - args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values); - caller.startPreferencePanel(PowerUsageDetail.class.getName(), args, - R.string.details_title, null, null, 0); - } - - /** - * Refreshes the power usage list. - * @param includeZeroConsumption whether includes those applications which have consumed very - * little power up till now. - */ - public void refreshStats(boolean includeZeroConsumption) { - // Initialize mStats if necessary. - getStats(); - - mMaxPower = 0; - mTotalPower = 0; - mWifiPower = 0; - mBluetoothPower = 0; - mAppWifiRunning = 0; - - mUsageList.clear(); - mWifiSippers.clear(); - mBluetoothSippers.clear(); - mUserSippers.clear(); - mUserPower.clear(); - - processAppUsage(includeZeroConsumption); - processMiscUsage(); - - Collections.sort(mUsageList); - - if (mHandler != null) { - synchronized (mRequestQueue) { - if (!mRequestQueue.isEmpty()) { - if (mRequestThread != null) { - mRequestThread.abort(); - } - mRequestThread = new NameAndIconLoader(); - mRequestThread.setPriority(Thread.MIN_PRIORITY); - mRequestThread.start(); - mRequestQueue.notify(); - } - } - } - } - - private void processAppUsage(boolean includeZeroConsumption) { - SensorManager sensorManager = (SensorManager) mActivity.getSystemService( - Context.SENSOR_SERVICE); - final int which = mStatsType; - final int speedSteps = mPowerProfile.getNumSpeedSteps(); - final double[] powerCpuNormal = new double[speedSteps]; - final long[] cpuSpeedStepTimes = new long[speedSteps]; - for (int p = 0; p < speedSteps; p++) { - powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p); - } - final double mobilePowerPerByte = getMobilePowerPerByte(); - final double wifiPowerPerByte = getWifiPowerPerByte(); - long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); - long appWakelockTime = 0; - BatterySipper osApp = null; - mStatsPeriod = uSecTime; - SparseArray<? extends Uid> uidStats = mStats.getUidStats(); - final int NU = uidStats.size(); - for (int iu = 0; iu < NU; iu++) { - Uid u = uidStats.valueAt(iu); - double p; // in mAs - double power = 0; // in mAs - double highestDrain = 0; - String packageWithHighestDrain = null; - //mUsageList.add(new AppUsage(u.getUid(), new double[] {power})); - Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); - long cpuTime = 0; - long cpuFgTime = 0; - long wakelockTime = 0; - long gpsTime = 0; - if (DEBUG) Log.i(TAG, "UID " + u.getUid()); - if (processStats.size() > 0) { - // Process CPU time - for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent - : processStats.entrySet()) { - Uid.Proc ps = ent.getValue(); - final long userTime = ps.getUserTime(which); - final long systemTime = ps.getSystemTime(which); - final long foregroundTime = ps.getForegroundTime(which); - cpuFgTime += foregroundTime * 10; // convert to millis - final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis - int totalTimeAtSpeeds = 0; - // Get the total first - for (int step = 0; step < speedSteps; step++) { - cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which); - totalTimeAtSpeeds += cpuSpeedStepTimes[step]; - } - if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1; - // Then compute the ratio of time spent at each speed - double processPower = 0; - for (int step = 0; step < speedSteps; step++) { - double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds; - processPower += ratio * tmpCpuTime * powerCpuNormal[step]; - } - cpuTime += tmpCpuTime; - if (DEBUG && processPower != 0) { - Log.i(TAG, String.format("process %s, cpu power=%.2f", - ent.getKey(), processPower / 1000)); - } - power += processPower; - if (packageWithHighestDrain == null - || packageWithHighestDrain.startsWith("*")) { - highestDrain = processPower; - packageWithHighestDrain = ent.getKey(); - } else if (highestDrain < processPower - && !ent.getKey().startsWith("*")) { - highestDrain = processPower; - packageWithHighestDrain = ent.getKey(); - } - } - } - if (cpuFgTime > cpuTime) { - if (DEBUG && cpuFgTime > cpuTime + 10000) { - Log.i(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time"); - } - cpuTime = cpuFgTime; // Statistics may not have been gathered yet. - } - power /= 1000; - if (DEBUG && power != 0) Log.i(TAG, String.format("total cpu power=%.2f", power)); - - // Process wake lock usage - Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats(); - for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry - : wakelockStats.entrySet()) { - Uid.Wakelock wakelock = wakelockEntry.getValue(); - // Only care about partial wake locks since full wake locks - // are canceled when the user turns the screen off. - BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); - if (timer != null) { - wakelockTime += timer.getTotalTimeLocked(uSecTime, which); - } - } - wakelockTime /= 1000; // convert to millis - appWakelockTime += wakelockTime; - - // Add cost of holding a wake lock - p = (wakelockTime - * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; - power += p; - if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p)); - - // Add cost of mobile traffic - final long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); - final long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); - p = (mobileRx + mobileTx) * mobilePowerPerByte; - power += p; - if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p)); - - // Add cost of wifi traffic - final long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, mStatsType); - final long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, mStatsType); - p = (wifiRx + wifiTx) * wifiPowerPerByte; - power += p; - if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p)); - - // Add cost of keeping WIFI running. - long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000; - mAppWifiRunning += wifiRunningTimeMs; - p = (wifiRunningTimeMs - * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; - power += p; - if (DEBUG && p != 0) Log.i(TAG, String.format("wifi running power=%.2f", p)); - - // Add cost of WIFI scans - long wifiScanTimeMs = u.getWifiScanTime(uSecTime, which) / 1000; - p = (wifiScanTimeMs - * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / 1000; - power += p; - if (DEBUG && p != 0) Log.i(TAG, String.format("wifi scanning power=%.2f", p)); - for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) { - long batchScanTimeMs = u.getWifiBatchedScanTime(bin, uSecTime, which) / 1000; - p = (batchScanTimeMs - * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin)); - power += p; - if (DEBUG && p != 0) { - Log.i(TAG, String.format("wifi batched scanning lvl %d = %.2f", bin, p)); - } - } - - // Process Sensor usage - Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); - for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry - : sensorStats.entrySet()) { - Uid.Sensor sensor = sensorEntry.getValue(); - int sensorHandle = sensor.getHandle(); - BatteryStats.Timer timer = sensor.getSensorTime(); - long sensorTime = timer.getTotalTimeLocked(uSecTime, which) / 1000; - double multiplier = 0; - switch (sensorHandle) { - case Uid.Sensor.GPS: - multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON); - gpsTime = sensorTime; - break; - default: - List<Sensor> sensorList = sensorManager.getSensorList( - android.hardware.Sensor.TYPE_ALL); - for (android.hardware.Sensor s : sensorList) { - if (s.getHandle() == sensorHandle) { - multiplier = s.getPower(); - break; - } - } - } - p = (multiplier * sensorTime) / 1000; - power += p; - if (DEBUG && p != 0) { - Log.i(TAG, String.format("sensor %s power=%.2f", sensor.toString(), p)); - } - } - - if (DEBUG) Log.i(TAG, String.format("UID %d total power=%.2f", u.getUid(), power)); - - // Add the app to the list if it is consuming power - boolean isOtherUser = false; - final int userId = UserHandle.getUserId(u.getUid()); - if (power != 0 || includeZeroConsumption || u.getUid() == 0) { - BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler, - packageWithHighestDrain, DrainType.APP, 0, u, - new double[] {power}); - app.cpuTime = cpuTime; - app.gpsTime = gpsTime; - app.wifiRunningTime = wifiRunningTimeMs; - app.cpuFgTime = cpuFgTime; - app.wakeLockTime = wakelockTime; - app.mobileRxBytes = mobileRx; - app.mobileTxBytes = mobileTx; - app.wifiRxBytes = wifiRx; - app.wifiTxBytes = wifiTx; - if (u.getUid() == Process.WIFI_UID) { - mWifiSippers.add(app); - } else if (u.getUid() == Process.BLUETOOTH_UID) { - mBluetoothSippers.add(app); - } else if (userId != UserHandle.myUserId() - && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) { - isOtherUser = true; - List<BatterySipper> list = mUserSippers.get(userId); - if (list == null) { - list = new ArrayList<BatterySipper>(); - mUserSippers.put(userId, list); - } - list.add(app); - } else { - mUsageList.add(app); - } - if (u.getUid() == 0) { - osApp = app; - } - } - if (power != 0 || includeZeroConsumption) { - if (u.getUid() == Process.WIFI_UID) { - mWifiPower += power; - } else if (u.getUid() == Process.BLUETOOTH_UID) { - mBluetoothPower += power; - } else if (isOtherUser) { - Double userPower = mUserPower.get(userId); - if (userPower == null) { - userPower = power; - } else { - userPower += power; - } - mUserPower.put(userId, userPower); - } else { - if (power > mMaxPower) mMaxPower = power; - mTotalPower += power; - } - } - } - - // The device has probably been awake for longer than the screen on - // time and application wake lock time would account for. Assign - // this remainder to the OS, if possible. - if (osApp != null) { - long wakeTimeMillis = mStats.computeBatteryUptime( - SystemClock.uptimeMillis() * 1000, which) / 1000; - wakeTimeMillis -= appWakelockTime + (mStats.getScreenOnTime( - SystemClock.elapsedRealtime(), which) / 1000); - if (wakeTimeMillis > 0) { - double power = (wakeTimeMillis - * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; - if (DEBUG) Log.i(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " + power); - osApp.wakeLockTime += wakeTimeMillis; - osApp.value += power; - osApp.values[0] += power; - if (osApp.value > mMaxPower) mMaxPower = osApp.value; - mTotalPower += power; - } - } - } - - private void addPhoneUsage(long uSecNow) { - long phoneOnTimeMs = mStats.getPhoneOnTime(uSecNow, mStatsType) / 1000; - double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) - * phoneOnTimeMs / 1000; - addEntry(mActivity.getString(R.string.power_phone), DrainType.PHONE, phoneOnTimeMs, - R.drawable.ic_settings_voice_calls, phoneOnPower); - } - - private void addScreenUsage(long uSecNow) { - double power = 0; - long screenOnTimeMs = mStats.getScreenOnTime(uSecNow, mStatsType) / 1000; - power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON); - final double screenFullPower = - mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL); - for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) { - double screenBinPower = screenFullPower * (i + 0.5f) - / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; - long brightnessTime = mStats.getScreenBrightnessTime(i, uSecNow, mStatsType) / 1000; - power += screenBinPower * brightnessTime; - if (DEBUG) { - Log.i(TAG, "Screen bin power = " + (int) screenBinPower + ", time = " - + brightnessTime); - } - } - power /= 1000; // To seconds - addEntry(mActivity.getString(R.string.power_screen), DrainType.SCREEN, screenOnTimeMs, - R.drawable.ic_settings_display, power); - } - - private void addRadioUsage(long uSecNow) { - double power = 0; - final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; - long signalTimeMs = 0; - for (int i = 0; i < BINS; i++) { - long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, uSecNow, mStatsType) / 1000; - power += strengthTimeMs / 1000 - * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i); - signalTimeMs += strengthTimeMs; - } - long scanningTimeMs = mStats.getPhoneSignalScanningTime(uSecNow, mStatsType) / 1000; - power += scanningTimeMs / 1000 * mPowerProfile.getAveragePower( - PowerProfile.POWER_RADIO_SCANNING); - BatterySipper bs = - addEntry(mActivity.getString(R.string.power_cell), DrainType.CELL, - signalTimeMs, R.drawable.ic_settings_cell_standby, power); - if (signalTimeMs != 0) { - bs.noCoveragePercent = mStats.getPhoneSignalStrengthTime(0, uSecNow, mStatsType) - / 1000 * 100.0 / signalTimeMs; - } - } - - private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) { - for (int i=0; i<from.size(); i++) { - BatterySipper wbs = from.get(i); - if (DEBUG) Log.i(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime); - bs.cpuTime += wbs.cpuTime; - bs.gpsTime += wbs.gpsTime; - bs.wifiRunningTime += wbs.wifiRunningTime; - bs.cpuFgTime += wbs.cpuFgTime; - bs.wakeLockTime += wbs.wakeLockTime; - bs.mobileRxBytes += wbs.mobileRxBytes; - bs.mobileTxBytes += wbs.mobileTxBytes; - bs.wifiRxBytes += wbs.wifiRxBytes; - bs.wifiTxBytes += wbs.wifiTxBytes; - } - } - - private void addWiFiUsage(long uSecNow) { - long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; - long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; - if (DEBUG) Log.i(TAG, "WIFI runningTime=" + runningTimeMs - + " app runningTime=" + mAppWifiRunning); - runningTimeMs -= mAppWifiRunning; - if (runningTimeMs < 0) runningTimeMs = 0; - double wifiPower = (onTimeMs * 0 /* TODO */ - * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON) - + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; - if (DEBUG) Log.i(TAG, "WIFI power=" + wifiPower + " from procs=" + mWifiPower); - BatterySipper bs = addEntry(mActivity.getString(R.string.power_wifi), DrainType.WIFI, - runningTimeMs, R.drawable.ic_settings_wifi, wifiPower + mWifiPower); - aggregateSippers(bs, mWifiSippers, "WIFI"); - } - - private void addIdleUsage(long uSecNow) { - long idleTimeMs = (uSecNow - mStats.getScreenOnTime(uSecNow, mStatsType)) / 1000; - double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE)) - / 1000; - addEntry(mActivity.getString(R.string.power_idle), DrainType.IDLE, idleTimeMs, - R.drawable.ic_settings_phone_idle, idlePower); - } - - private void addBluetoothUsage(long uSecNow) { - long btOnTimeMs = mStats.getBluetoothOnTime(uSecNow, mStatsType) / 1000; - double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON) - / 1000; - int btPingCount = mStats.getBluetoothPingCount(); - btPower += (btPingCount - * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; - BatterySipper bs = addEntry(mActivity.getString(R.string.power_bluetooth), - DrainType.BLUETOOTH, btOnTimeMs, R.drawable.ic_settings_bluetooth, - btPower + mBluetoothPower); - aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); - } - - private void addUserUsage() { - for (int i=0; i<mUserSippers.size(); i++) { - final int userId = mUserSippers.keyAt(i); - final List<BatterySipper> sippers = mUserSippers.valueAt(i); - UserInfo info = mUm.getUserInfo(userId); - Drawable icon; - String name; - if (info != null) { - icon = UserUtils.getUserIcon(mActivity, mUm, info, mActivity.getResources()); - name = info != null ? info.name : null; - if (name == null) { - name = Integer.toString(info.id); - } - name = mActivity.getResources().getString( - R.string.running_process_item_user_label, name); - } else { - icon = null; - name = mActivity.getResources().getString( - R.string.running_process_item_removed_user_label); - } - Double userPower = mUserPower.get(userId); - double power = (userPower != null) ? userPower : 0.0; - BatterySipper bs = addEntry(name, DrainType.USER, 0, 0, power); - bs.icon = icon; - aggregateSippers(bs, sippers, "User"); - } - } - - /** - * Return estimated power (in mAs) of sending a byte with the mobile radio. - */ - private double getMobilePowerPerByte() { - final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system - final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) - / 3600; - - final long mobileRx = mStats.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); - final long mobileTx = mStats.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); - final long mobileData = mobileRx + mobileTx; - - final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000; - final long mobileBps = radioDataUptimeMs != 0 - ? mobileData * 8 * 1000 / radioDataUptimeMs - : MOBILE_BPS; - - return MOBILE_POWER / (mobileBps / 8); - } - - /** - * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio. - */ - private double getWifiPowerPerByte() { - final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system - final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE) - / 3600; - return WIFI_POWER / (WIFI_BPS / 8); - } - - private void processMiscUsage() { - final int which = mStatsType; - long uSecTime = SystemClock.elapsedRealtime() * 1000; - final long uSecNow = mStats.computeBatteryRealtime(uSecTime, which); - final long timeSinceUnplugged = uSecNow; - if (DEBUG) { - Log.i(TAG, "Uptime since last unplugged = " + (timeSinceUnplugged / 1000)); - } - - addUserUsage(); - addPhoneUsage(uSecNow); - addScreenUsage(uSecNow); - addWiFiUsage(uSecNow); - addBluetoothUsage(uSecNow); - addIdleUsage(uSecNow); // Not including cellular idle power - // Don't compute radio usage if it's a wifi-only device - if (!com.android.settings.Utils.isWifiOnly(mActivity)) { - addRadioUsage(uSecNow); - } - } - - private BatterySipper addEntry(String label, DrainType drainType, long time, int iconId, - double power) { - if (power > mMaxPower) mMaxPower = power; - mTotalPower += power; - BatterySipper bs = new BatterySipper(mActivity, mRequestQueue, mHandler, - label, drainType, iconId, null, new double[] {power}); - bs.usageTime = time; - bs.iconId = iconId; - mUsageList.add(bs); - return bs; - } - - public List<BatterySipper> getUsageList() { - return mUsageList; - } - - static final int MSG_UPDATE_NAME_ICON = 1; - static final int MSG_REPORT_FULLY_DRAWN = 2; - - public double getMaxPower() { - return mMaxPower; - } - - public double getTotalPower() { - return mTotalPower; - } - - private void load() { - try { - byte[] data = mBatteryInfo.getStatistics(); - Parcel parcel = Parcel.obtain(); - parcel.unmarshall(data, 0, data.length); - parcel.setDataPosition(0); - mStats = com.android.internal.os.BatteryStatsImpl.CREATOR - .createFromParcel(parcel); - mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException:", e); - } - } -} |