Search in sources :

Example 6 with BatterySipper

use of com.android.internal.os.BatterySipper in project android_frameworks_base by AOSPA.

the class BatteryStats method dumpCheckinLocked.

/**
     * Checkin server version of dump to produce more compact, computer-readable log.
     * 
     * NOTE: all times are expressed in 'ms'.
     */
public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly) {
    final long rawUptime = SystemClock.uptimeMillis() * 1000;
    final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
    final long batteryUptime = getBatteryUptime(rawUptime);
    final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
    final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
    final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
    final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, which);
    final long totalRealtime = computeRealtime(rawRealtime, which);
    final long totalUptime = computeUptime(rawUptime, which);
    final long screenOnTime = getScreenOnTime(rawRealtime, which);
    final long interactiveTime = getInteractiveTime(rawRealtime, which);
    final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
    final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final int connChanges = getNumConnectivityChange(which);
    final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
    final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which);
    final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter().getCountLocked(which);
    final StringBuilder sb = new StringBuilder(128);
    final SparseArray<? extends Uid> uidStats = getUidStats();
    final int NU = uidStats.size();
    final String category = STAT_NAMES[which];
    // Dump "battery" stat
    dumpLine(pw, 0, /* uid */
    category, BATTERY_DATA, which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", whichBatteryRealtime / 1000, whichBatteryUptime / 1000, totalRealtime / 1000, totalUptime / 1000, getStartClockTime(), whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000, getEstimatedBatteryCapacity());
    // Calculate wakelock times across all uids.
    long fullWakeLockTimeTotal = 0;
    long partialWakeLockTimeTotal = 0;
    for (int iu = 0; iu < NU; iu++) {
        final Uid u = uidStats.valueAt(iu);
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
            if (fullWakeTimer != null) {
                fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
            final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
            if (partialWakeTimer != null) {
                partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
        }
    }
    // Dump network stats
    final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
    final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
    final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
    final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_NETWORK_DATA, mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets, btRxTotalBytes, btTxTotalBytes);
    // Dump Modem controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_MODEM_CONTROLLER_DATA, getModemControllerActivity(), which);
    // Dump Wifi controller stats
    final long wifiOnTime = getWifiOnTime(rawRealtime, which);
    final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_DATA, wifiOnTime / 1000, wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */
    0, 0, 0);
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_CONTROLLER_DATA, getWifiControllerActivity(), which);
    // Dump Bluetooth controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_BLUETOOTH_CONTROLLER_DATA, getBluetoothControllerActivity(), which);
    // Dump misc stats
    dumpLine(pw, 0, /* uid */
    category, MISC_DATA, screenOnTime / 1000, phoneOnTime / 1000, fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000, getMobileRadioActiveTime(rawRealtime, which) / 1000, getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which), getMobileRadioActiveCount(which), getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
    // Dump screen brightness stats
    Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
    for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
        args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SCREEN_BRIGHTNESS_DATA, args);
    // Dump signal strength stats
    args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_TIME_DATA, args);
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_SCANNING_TIME_DATA, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_COUNT_DATA, args);
    // Dump network type stats
    args = new Object[NUM_DATA_CONNECTION_TYPES];
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_TIME_DATA, args);
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_COUNT_DATA, args);
    // Dump wifi state stats
    args = new Object[NUM_WIFI_STATES];
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_COUNT_DATA, args);
    // Dump wifi suppl state stats
    args = new Object[NUM_WIFI_SUPPL_STATES];
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_COUNT_DATA, args);
    // Dump wifi signal strength stats
    args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), getDischargeCurrentLevel());
    }
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeAmountScreenOn(), getDischargeAmountScreenOff(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    } else {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), getDischargeAmountScreenOnSinceCharge(), getDischargeAmountScreenOffSinceCharge(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    }
    if (reqUid < 0) {
        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
        if (kernelWakelocks.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
                sb.setLength(0);
                printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
                dumpLine(pw, 0, /* uid */
                category, KERNEL_WAKELOCK_DATA, ent.getKey(), sb.toString());
            }
        }
        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
        if (wakeupReasons.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
                // Not doing the regular wake lock formatting to remain compatible
                // with the old checkin format.
                long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
                int count = ent.getValue().getCountLocked(which);
                dumpLine(pw, 0, /* uid */
                category, WAKEUP_REASON_DATA, "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
            }
        }
    }
    final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
    helper.create(this);
    helper.refreshStats(which, UserHandle.USER_ALL);
    final List<BatterySipper> sippers = helper.getUsageList();
    if (sippers != null && sippers.size() > 0) {
        dumpLine(pw, 0, /* uid */
        category, POWER_USE_SUMMARY_DATA, BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()), BatteryStatsHelper.makemAh(helper.getComputedPower()), BatteryStatsHelper.makemAh(helper.getMinDrainedPower()), BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            int uid = 0;
            String label;
            switch(bs.drainType) {
                case IDLE:
                    label = "idle";
                    break;
                case CELL:
                    label = "cell";
                    break;
                case PHONE:
                    label = "phone";
                    break;
                case WIFI:
                    label = "wifi";
                    break;
                case BLUETOOTH:
                    label = "blue";
                    break;
                case SCREEN:
                    label = "scrn";
                    break;
                case FLASHLIGHT:
                    label = "flashlight";
                    break;
                case APP:
                    uid = bs.uidObj.getUid();
                    label = "uid";
                    break;
                case USER:
                    uid = UserHandle.getUid(bs.userId, 0);
                    label = "user";
                    break;
                case UNACCOUNTED:
                    label = "unacc";
                    break;
                case OVERCOUNTED:
                    label = "over";
                    break;
                case CAMERA:
                    label = "camera";
                    break;
                default:
                    label = "???";
            }
            dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, BatteryStatsHelper.makemAh(bs.totalPowerMah));
        }
    }
    for (int iu = 0; iu < NU; iu++) {
        final int uid = uidStats.keyAt(iu);
        if (reqUid >= 0 && uid != reqUid) {
            continue;
        }
        final Uid u = uidStats.valueAt(iu);
        // Dump Network stats per uid, if any
        final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
        final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
        final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
        final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
        final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
        final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
        final long mobileActiveTime = u.getMobileRadioActiveTime(which);
        final int mobileActiveCount = u.getMobileRadioActiveCount(which);
        final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
        final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
        final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
        final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
        final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
        if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0 || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0 || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0 || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0) {
            dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx, wifiBytesRx, wifiBytesTx, mobilePacketsRx, mobilePacketsTx, wifiPacketsRx, wifiPacketsTx, mobileActiveTime, mobileActiveCount, btBytesRx, btBytesTx, mobileWakeup, wifiWakeup);
        }
        // Dump modem controller data, per UID.
        dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA, u.getModemControllerActivity(), which);
        // Dump Wifi controller data, per UID.
        final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
        final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
        final int wifiScanCount = u.getWifiScanCount(which);
        final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
        if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 || uidWifiRunningTime != 0) {
            dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime, wifiScanCount, /* legacy fields follow, keep at 0 */
            0, 0, 0);
        }
        dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA, u.getWifiControllerActivity(), which);
        dumpTimer(pw, uid, category, BLUETOOTH_MISC_DATA, u.getBluetoothScanTimer(), rawRealtime, which);
        dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA, u.getBluetoothControllerActivity(), which);
        if (u.hasUserActivity()) {
            args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
            boolean hasData = false;
            for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                int val = u.getUserActivityCount(i, which);
                args[i] = val;
                if (val != 0)
                    hasData = true;
            }
            if (hasData) {
                dumpLine(pw, uid, /* uid */
                category, USER_ACTIVITY_DATA, args);
            }
        }
        final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            String linePrefix = "";
            sb.setLength(0);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "f", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, "p", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "w", which, linePrefix);
            // Only log if we had at lease one wakelock...
            if (sb.length() > 0) {
                String name = wakelocks.keyAt(iw);
                if (name.indexOf(',') >= 0) {
                    name = name.replace(',', '_');
                }
                dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
            }
        }
        final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
        for (int isy = syncs.size() - 1; isy >= 0; isy--) {
            final Timer timer = syncs.valueAt(isy);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
            }
        }
        final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
        for (int ij = jobs.size() - 1; ij >= 0; ij--) {
            final Timer timer = jobs.valueAt(ij);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
            }
        }
        dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(), rawRealtime, which);
        final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
        final int NSE = sensors.size();
        for (int ise = 0; ise < NSE; ise++) {
            final Uid.Sensor se = sensors.valueAt(ise);
            final int sensorNumber = sensors.keyAt(ise);
            final Timer timer = se.getSensorTime();
            if (timer != null) {
                // Convert from microseconds to milliseconds with rounding
                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final int count = timer.getCountLocked(which);
                if (totalTime != 0) {
                    dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
                }
            }
        }
        dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(), rawRealtime, which);
        final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
        long totalStateTime = 0;
        for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ips++) {
            final long time = u.getProcessStateTime(ips, rawRealtime, which);
            totalStateTime += time;
            stateTimes[ips] = (time + 500) / 1000;
        }
        if (totalStateTime > 0) {
            dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
        }
        final long userCpuTimeUs = u.getUserCpuTimeUs(which);
        final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
        final long powerCpuMaUs = u.getCpuPowerMaUs(which);
        if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
            dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000, powerCpuMaUs / 1000);
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
        for (int ipr = processStats.size() - 1; ipr >= 0; ipr--) {
            final Uid.Proc ps = processStats.valueAt(ipr);
            final long userMillis = ps.getUserTime(which);
            final long systemMillis = ps.getSystemTime(which);
            final long foregroundMillis = ps.getForegroundTime(which);
            final int starts = ps.getStarts(which);
            final int numCrashes = ps.getNumCrashes(which);
            final int numAnrs = ps.getNumAnrs(which);
            if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 || starts != 0 || numAnrs != 0 || numCrashes != 0) {
                dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            final Uid.Pkg ps = packageStats.valueAt(ipkg);
            int wakeups = 0;
            final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                int count = alarms.valueAt(iwa).getCountLocked(which);
                wakeups += count;
                String name = alarms.keyAt(iwa).replace(',', '_');
                dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
            }
            final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
            for (int isvc = serviceStats.size() - 1; isvc >= 0; isvc--) {
                final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
                final long startTime = ss.getStartTime(batteryUptime, which);
                final int starts = ss.getStarts(which);
                final int launches = ss.getLaunches(which);
                if (startTime != 0 || starts != 0 || launches != 0) {
                    dumpLine(pw, uid, category, APK_DATA, // wakeup alarms
                    wakeups, // Apk
                    packageStats.keyAt(ipkg), // service
                    serviceStats.keyAt(isvc), // time spent started, in ms
                    startTime / 1000, starts, launches);
                }
            }
        }
    }
}
Also used : BatterySipper(com.android.internal.os.BatterySipper) HashMap(java.util.HashMap) Map(java.util.Map) ArrayMap(android.util.ArrayMap) BatteryStatsHelper(com.android.internal.os.BatteryStatsHelper)

Example 7 with BatterySipper

use of com.android.internal.os.BatterySipper in project android_frameworks_base by crdroidandroid.

the class BatteryStats method dumpCheckinLocked.

/**
     * Checkin server version of dump to produce more compact, computer-readable log.
     * 
     * NOTE: all times are expressed in 'ms'.
     */
public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly) {
    final long rawUptime = SystemClock.uptimeMillis() * 1000;
    final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
    final long batteryUptime = getBatteryUptime(rawUptime);
    final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
    final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
    final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
    final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, which);
    final long totalRealtime = computeRealtime(rawRealtime, which);
    final long totalUptime = computeUptime(rawUptime, which);
    final long screenOnTime = getScreenOnTime(rawRealtime, which);
    final long interactiveTime = getInteractiveTime(rawRealtime, which);
    final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
    final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final int connChanges = getNumConnectivityChange(which);
    final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
    final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which);
    final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter().getCountLocked(which);
    final StringBuilder sb = new StringBuilder(128);
    final SparseArray<? extends Uid> uidStats = getUidStats();
    final int NU = uidStats.size();
    final String category = STAT_NAMES[which];
    // Dump "battery" stat
    dumpLine(pw, 0, /* uid */
    category, BATTERY_DATA, which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", whichBatteryRealtime / 1000, whichBatteryUptime / 1000, totalRealtime / 1000, totalUptime / 1000, getStartClockTime(), whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000, getEstimatedBatteryCapacity());
    // Calculate wakelock times across all uids.
    long fullWakeLockTimeTotal = 0;
    long partialWakeLockTimeTotal = 0;
    for (int iu = 0; iu < NU; iu++) {
        final Uid u = uidStats.valueAt(iu);
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
            if (fullWakeTimer != null) {
                fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
            final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
            if (partialWakeTimer != null) {
                partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
        }
    }
    // Dump network stats
    final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
    final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
    final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
    final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_NETWORK_DATA, mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets, btRxTotalBytes, btTxTotalBytes);
    // Dump Modem controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_MODEM_CONTROLLER_DATA, getModemControllerActivity(), which);
    // Dump Wifi controller stats
    final long wifiOnTime = getWifiOnTime(rawRealtime, which);
    final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_DATA, wifiOnTime / 1000, wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */
    0, 0, 0);
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_CONTROLLER_DATA, getWifiControllerActivity(), which);
    // Dump Bluetooth controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_BLUETOOTH_CONTROLLER_DATA, getBluetoothControllerActivity(), which);
    // Dump misc stats
    dumpLine(pw, 0, /* uid */
    category, MISC_DATA, screenOnTime / 1000, phoneOnTime / 1000, fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000, getMobileRadioActiveTime(rawRealtime, which) / 1000, getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which), getMobileRadioActiveCount(which), getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
    // Dump screen brightness stats
    Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
    for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
        args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SCREEN_BRIGHTNESS_DATA, args);
    // Dump signal strength stats
    args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_TIME_DATA, args);
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_SCANNING_TIME_DATA, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_COUNT_DATA, args);
    // Dump network type stats
    args = new Object[NUM_DATA_CONNECTION_TYPES];
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_TIME_DATA, args);
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_COUNT_DATA, args);
    // Dump wifi state stats
    args = new Object[NUM_WIFI_STATES];
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_COUNT_DATA, args);
    // Dump wifi suppl state stats
    args = new Object[NUM_WIFI_SUPPL_STATES];
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_COUNT_DATA, args);
    // Dump wifi signal strength stats
    args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), getDischargeCurrentLevel());
    }
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeAmountScreenOn(), getDischargeAmountScreenOff(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    } else {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), getDischargeAmountScreenOnSinceCharge(), getDischargeAmountScreenOffSinceCharge(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    }
    if (reqUid < 0) {
        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
        if (kernelWakelocks.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
                sb.setLength(0);
                printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
                dumpLine(pw, 0, /* uid */
                category, KERNEL_WAKELOCK_DATA, ent.getKey(), sb.toString());
            }
        }
        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
        if (wakeupReasons.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
                // Not doing the regular wake lock formatting to remain compatible
                // with the old checkin format.
                long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
                int count = ent.getValue().getCountLocked(which);
                dumpLine(pw, 0, /* uid */
                category, WAKEUP_REASON_DATA, "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
            }
        }
    }
    final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
    helper.create(this);
    helper.refreshStats(which, UserHandle.USER_ALL);
    final List<BatterySipper> sippers = helper.getUsageList();
    if (sippers != null && sippers.size() > 0) {
        dumpLine(pw, 0, /* uid */
        category, POWER_USE_SUMMARY_DATA, BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()), BatteryStatsHelper.makemAh(helper.getComputedPower()), BatteryStatsHelper.makemAh(helper.getMinDrainedPower()), BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            int uid = 0;
            String label;
            switch(bs.drainType) {
                case IDLE:
                    label = "idle";
                    break;
                case CELL:
                    label = "cell";
                    break;
                case PHONE:
                    label = "phone";
                    break;
                case WIFI:
                    label = "wifi";
                    break;
                case BLUETOOTH:
                    label = "blue";
                    break;
                case SCREEN:
                    label = "scrn";
                    break;
                case FLASHLIGHT:
                    label = "flashlight";
                    break;
                case APP:
                    uid = bs.uidObj.getUid();
                    label = "uid";
                    break;
                case USER:
                    uid = UserHandle.getUid(bs.userId, 0);
                    label = "user";
                    break;
                case UNACCOUNTED:
                    label = "unacc";
                    break;
                case OVERCOUNTED:
                    label = "over";
                    break;
                case CAMERA:
                    label = "camera";
                    break;
                default:
                    label = "???";
            }
            dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, BatteryStatsHelper.makemAh(bs.totalPowerMah));
        }
    }
    for (int iu = 0; iu < NU; iu++) {
        final int uid = uidStats.keyAt(iu);
        if (reqUid >= 0 && uid != reqUid) {
            continue;
        }
        final Uid u = uidStats.valueAt(iu);
        // Dump Network stats per uid, if any
        final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
        final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
        final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
        final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
        final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
        final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
        final long mobileActiveTime = u.getMobileRadioActiveTime(which);
        final int mobileActiveCount = u.getMobileRadioActiveCount(which);
        final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
        final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
        final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
        final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
        final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
        if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0 || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0 || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0 || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0) {
            dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx, wifiBytesRx, wifiBytesTx, mobilePacketsRx, mobilePacketsTx, wifiPacketsRx, wifiPacketsTx, mobileActiveTime, mobileActiveCount, btBytesRx, btBytesTx, mobileWakeup, wifiWakeup);
        }
        // Dump modem controller data, per UID.
        dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA, u.getModemControllerActivity(), which);
        // Dump Wifi controller data, per UID.
        final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
        final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
        final int wifiScanCount = u.getWifiScanCount(which);
        final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
        if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 || uidWifiRunningTime != 0) {
            dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime, wifiScanCount, /* legacy fields follow, keep at 0 */
            0, 0, 0);
        }
        dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA, u.getWifiControllerActivity(), which);
        dumpTimer(pw, uid, category, BLUETOOTH_MISC_DATA, u.getBluetoothScanTimer(), rawRealtime, which);
        dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA, u.getBluetoothControllerActivity(), which);
        if (u.hasUserActivity()) {
            args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
            boolean hasData = false;
            for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                int val = u.getUserActivityCount(i, which);
                args[i] = val;
                if (val != 0)
                    hasData = true;
            }
            if (hasData) {
                dumpLine(pw, uid, /* uid */
                category, USER_ACTIVITY_DATA, args);
            }
        }
        final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            String linePrefix = "";
            sb.setLength(0);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "f", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, "p", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "w", which, linePrefix);
            // Only log if we had at lease one wakelock...
            if (sb.length() > 0) {
                String name = wakelocks.keyAt(iw);
                if (name.indexOf(',') >= 0) {
                    name = name.replace(',', '_');
                }
                dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
            }
        }
        final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
        for (int isy = syncs.size() - 1; isy >= 0; isy--) {
            final Timer timer = syncs.valueAt(isy);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
            }
        }
        final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
        for (int ij = jobs.size() - 1; ij >= 0; ij--) {
            final Timer timer = jobs.valueAt(ij);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
            }
        }
        dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(), rawRealtime, which);
        final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
        final int NSE = sensors.size();
        for (int ise = 0; ise < NSE; ise++) {
            final Uid.Sensor se = sensors.valueAt(ise);
            final int sensorNumber = sensors.keyAt(ise);
            final Timer timer = se.getSensorTime();
            if (timer != null) {
                // Convert from microseconds to milliseconds with rounding
                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final int count = timer.getCountLocked(which);
                if (totalTime != 0) {
                    dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
                }
            }
        }
        dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(), rawRealtime, which);
        final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
        long totalStateTime = 0;
        for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ips++) {
            final long time = u.getProcessStateTime(ips, rawRealtime, which);
            totalStateTime += time;
            stateTimes[ips] = (time + 500) / 1000;
        }
        if (totalStateTime > 0) {
            dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
        }
        final long userCpuTimeUs = u.getUserCpuTimeUs(which);
        final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
        final long powerCpuMaUs = u.getCpuPowerMaUs(which);
        if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
            dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000, powerCpuMaUs / 1000);
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
        for (int ipr = processStats.size() - 1; ipr >= 0; ipr--) {
            final Uid.Proc ps = processStats.valueAt(ipr);
            final long userMillis = ps.getUserTime(which);
            final long systemMillis = ps.getSystemTime(which);
            final long foregroundMillis = ps.getForegroundTime(which);
            final int starts = ps.getStarts(which);
            final int numCrashes = ps.getNumCrashes(which);
            final int numAnrs = ps.getNumAnrs(which);
            if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 || starts != 0 || numAnrs != 0 || numCrashes != 0) {
                dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            final Uid.Pkg ps = packageStats.valueAt(ipkg);
            int wakeups = 0;
            final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                int count = alarms.valueAt(iwa).getCountLocked(which);
                wakeups += count;
                String name = alarms.keyAt(iwa).replace(',', '_');
                dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
            }
            final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
            for (int isvc = serviceStats.size() - 1; isvc >= 0; isvc--) {
                final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
                final long startTime = ss.getStartTime(batteryUptime, which);
                final int starts = ss.getStarts(which);
                final int launches = ss.getLaunches(which);
                if (startTime != 0 || starts != 0 || launches != 0) {
                    dumpLine(pw, uid, category, APK_DATA, // wakeup alarms
                    wakeups, // Apk
                    packageStats.keyAt(ipkg), // service
                    serviceStats.keyAt(isvc), // time spent started, in ms
                    startTime / 1000, starts, launches);
                }
            }
        }
    }
}
Also used : BatterySipper(com.android.internal.os.BatterySipper) HashMap(java.util.HashMap) Map(java.util.Map) ArrayMap(android.util.ArrayMap) BatteryStatsHelper(com.android.internal.os.BatteryStatsHelper)

Example 8 with BatterySipper

use of com.android.internal.os.BatterySipper in project android_frameworks_base by crdroidandroid.

the class BatteryStats method dumpLocked.

@SuppressWarnings("unused")
public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which, int reqUid, boolean wifiOnly) {
    final long rawUptime = SystemClock.uptimeMillis() * 1000;
    final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
    final long batteryUptime = getBatteryUptime(rawUptime);
    final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
    final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
    final long totalRealtime = computeRealtime(rawRealtime, which);
    final long totalUptime = computeUptime(rawUptime, which);
    final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
    final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, which);
    final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
    final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
    final StringBuilder sb = new StringBuilder(128);
    final SparseArray<? extends Uid> uidStats = getUidStats();
    final int NU = uidStats.size();
    final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
    if (estimatedBatteryCapacity > 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Estimated battery capacity: ");
        sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Time on battery: ");
    formatTimeMs(sb, whichBatteryRealtime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
    sb.append(") realtime, ");
    formatTimeMs(sb, whichBatteryUptime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
    sb.append(") uptime");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Time on battery screen off: ");
    formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
    sb.append(") realtime, ");
    formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
    sb.append(") uptime");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Total run time: ");
    formatTimeMs(sb, totalRealtime / 1000);
    sb.append("realtime, ");
    formatTimeMs(sb, totalUptime / 1000);
    sb.append("uptime");
    pw.println(sb.toString());
    if (batteryTimeRemaining >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Battery time remaining: ");
        formatTimeMs(sb, batteryTimeRemaining / 1000);
        pw.println(sb.toString());
    }
    if (chargeTimeRemaining >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Charge time remaining: ");
        formatTimeMs(sb, chargeTimeRemaining / 1000);
        pw.println(sb.toString());
    }
    final LongCounter dischargeCounter = getDischargeCoulombCounter();
    final long dischargeCount = dischargeCounter.getCountLocked(which);
    if (dischargeCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    final LongCounter dischargeScreenOffCounter = getDischargeScreenOffCoulombCounter();
    final long dischargeScreenOffCount = dischargeScreenOffCounter.getCountLocked(which);
    if (dischargeScreenOffCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Screen off discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount;
    if (dischargeScreenOnCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Screen on discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    pw.print("  Start clock time: ");
    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
    final long screenOnTime = getScreenOnTime(rawRealtime, which);
    final long interactiveTime = getInteractiveTime(rawRealtime, which);
    final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
    final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
    final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
    final long wifiOnTime = getWifiOnTime(rawRealtime, which);
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Screen on: ");
    formatTimeMs(sb, screenOnTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
    sb.append(") ");
    sb.append(getScreenOnCount(which));
    sb.append("x, Interactive: ");
    formatTimeMs(sb, interactiveTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
    sb.append(")");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Screen brightnesses:");
    boolean didOne = false;
    for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
        final long time = getScreenBrightnessTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, screenOnTime));
        sb.append(")");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    if (powerSaveModeEnabledTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Power save mode enabled: ");
        formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
    }
    if (deviceLightIdlingTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Device light idling: ");
        formatTimeMs(sb, deviceLightIdlingTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
        sb.append("x");
        pw.println(sb.toString());
    }
    if (deviceIdleModeLightTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Idle mode light time: ");
        formatTimeMs(sb, deviceIdleModeLightTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
        sb.append("x");
        sb.append(" -- longest ");
        formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
        pw.println(sb.toString());
    }
    if (deviceIdlingTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Device full idling: ");
        formatTimeMs(sb, deviceIdlingTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
        sb.append("x");
        pw.println(sb.toString());
    }
    if (deviceIdleModeFullTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Idle mode full time: ");
        formatTimeMs(sb, deviceIdleModeFullTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
        sb.append("x");
        sb.append(" -- longest ");
        formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
        pw.println(sb.toString());
    }
    if (phoneOnTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Active phone call: ");
        formatTimeMs(sb, phoneOnTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneOnCount(which));
        sb.append("x");
    }
    final int connChanges = getNumConnectivityChange(which);
    if (connChanges != 0) {
        pw.print(prefix);
        pw.print("  Connectivity changes: ");
        pw.println(connChanges);
    }
    // Calculate wakelock times across all uids.
    long fullWakeLockTimeTotalMicros = 0;
    long partialWakeLockTimeTotalMicros = 0;
    final ArrayList<TimerEntry> timers = new ArrayList<>();
    for (int iu = 0; iu < NU; iu++) {
        final Uid u = uidStats.valueAt(iu);
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
            if (fullWakeTimer != null) {
                fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
            final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
            if (partialWakeTimer != null) {
                final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(rawRealtime, which);
                if (totalTimeMicros > 0) {
                    if (reqUid < 0) {
                        // Only show the ordered list of all wake
                        // locks if the caller is not asking for data
                        // about a specific uid.
                        timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(), partialWakeTimer, totalTimeMicros));
                    }
                    partialWakeLockTimeTotalMicros += totalTimeMicros;
                }
            }
        }
    }
    final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
    final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
    final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
    final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
    if (fullWakeLockTimeTotalMicros != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Total full wakelock time: ");
        formatTimeMsNoSpace(sb, (fullWakeLockTimeTotalMicros + 500) / 1000);
        pw.println(sb.toString());
    }
    if (partialWakeLockTimeTotalMicros != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Total partial wakelock time: ");
        formatTimeMsNoSpace(sb, (partialWakeLockTimeTotalMicros + 500) / 1000);
        pw.println(sb.toString());
    }
    pw.print(prefix);
    pw.print("  Mobile total received: ");
    pw.print(formatBytesLocked(mobileRxTotalBytes));
    pw.print(", sent: ");
    pw.print(formatBytesLocked(mobileTxTotalBytes));
    pw.print(" (packets received ");
    pw.print(mobileRxTotalPackets);
    pw.print(", sent ");
    pw.print(mobileTxTotalPackets);
    pw.println(")");
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Phone signal levels:");
    didOne = false;
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneSignalStrengthCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Signal scanning time: ");
    formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Radio types:");
    didOne = false;
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(DATA_CONNECTION_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneDataConnectionCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Mobile radio active time: ");
    final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
    formatTimeMs(sb, mobileActiveTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
    sb.append(") ");
    sb.append(getMobileRadioActiveCount(which));
    sb.append("x");
    pw.println(sb.toString());
    final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
    if (mobileActiveUnknownTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Mobile radio active unknown time: ");
        formatTimeMs(sb, mobileActiveUnknownTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getMobileRadioActiveUnknownCount(which));
        sb.append("x");
        pw.println(sb.toString());
    }
    final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
    if (mobileActiveAdjustedTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Mobile radio active adjusted time: ");
        formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
    }
    printControllerActivity(pw, sb, prefix, "Radio", getModemControllerActivity(), which);
    pw.print(prefix);
    pw.print("  Wi-Fi total received: ");
    pw.print(formatBytesLocked(wifiRxTotalBytes));
    pw.print(", sent: ");
    pw.print(formatBytesLocked(wifiTxTotalBytes));
    pw.print(" (packets received ");
    pw.print(wifiRxTotalPackets);
    pw.print(", sent ");
    pw.print(wifiTxTotalPackets);
    pw.println(")");
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi on: ");
    formatTimeMs(sb, wifiOnTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
    sb.append("), Wifi running: ");
    formatTimeMs(sb, wifiRunningTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
    sb.append(")");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi states:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        final long time = getWifiStateTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        didOne = true;
        sb.append(WIFI_STATE_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiStateCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi supplicant states:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        final long time = getWifiSupplStateTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        didOne = true;
        sb.append(WIFI_SUPPL_STATE_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiSupplStateCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi signal levels:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append("level(");
        sb.append(i);
        sb.append(") ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiSignalStrengthCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which);
    pw.print(prefix);
    pw.print("  Bluetooth total received: ");
    pw.print(formatBytesLocked(btRxTotalBytes));
    pw.print(", sent: ");
    pw.println(formatBytesLocked(btTxTotalBytes));
    final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Bluetooth scan time: ");
    formatTimeMs(sb, bluetoothScanTimeMs);
    pw.println(sb.toString());
    printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(), which);
    pw.println();
    if (which == STATS_SINCE_UNPLUGGED) {
        if (getIsOnBattery()) {
            pw.print(prefix);
            pw.println("  Device is currently unplugged");
            pw.print(prefix);
            pw.print("    Discharge cycle start level: ");
            pw.println(getDischargeStartLevel());
            pw.print(prefix);
            pw.print("    Discharge cycle current level: ");
            pw.println(getDischargeCurrentLevel());
        } else {
            pw.print(prefix);
            pw.println("  Device is currently plugged into power");
            pw.print(prefix);
            pw.print("    Last discharge cycle start level: ");
            pw.println(getDischargeStartLevel());
            pw.print(prefix);
            pw.print("    Last discharge cycle end level: ");
            pw.println(getDischargeCurrentLevel());
        }
        pw.print(prefix);
        pw.print("    Amount discharged while screen on: ");
        pw.println(getDischargeAmountScreenOn());
        pw.print(prefix);
        pw.print("    Amount discharged while screen off: ");
        pw.println(getDischargeAmountScreenOff());
        pw.println(" ");
    } else {
        pw.print(prefix);
        pw.println("  Device battery use since last full charge");
        pw.print(prefix);
        pw.print("    Amount discharged (lower bound): ");
        pw.println(getLowDischargeAmountSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged (upper bound): ");
        pw.println(getHighDischargeAmountSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged while screen on: ");
        pw.println(getDischargeAmountScreenOnSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged while screen off: ");
        pw.println(getDischargeAmountScreenOffSinceCharge());
        pw.println();
    }
    final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
    helper.create(this);
    helper.refreshStats(which, UserHandle.USER_ALL);
    List<BatterySipper> sippers = helper.getUsageList();
    if (sippers != null && sippers.size() > 0) {
        pw.print(prefix);
        pw.println("  Estimated power use (mAh):");
        pw.print(prefix);
        pw.print("    Capacity: ");
        printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
        pw.print(", Computed drain: ");
        printmAh(pw, helper.getComputedPower());
        pw.print(", actual drain: ");
        printmAh(pw, helper.getMinDrainedPower());
        if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
            pw.print("-");
            printmAh(pw, helper.getMaxDrainedPower());
        }
        pw.println();
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            pw.print(prefix);
            switch(bs.drainType) {
                case IDLE:
                    pw.print("    Idle: ");
                    break;
                case CELL:
                    pw.print("    Cell standby: ");
                    break;
                case PHONE:
                    pw.print("    Phone calls: ");
                    break;
                case WIFI:
                    pw.print("    Wifi: ");
                    break;
                case BLUETOOTH:
                    pw.print("    Bluetooth: ");
                    break;
                case SCREEN:
                    pw.print("    Screen: ");
                    break;
                case FLASHLIGHT:
                    pw.print("    Flashlight: ");
                    break;
                case APP:
                    pw.print("    Uid ");
                    UserHandle.formatUid(pw, bs.uidObj.getUid());
                    pw.print(": ");
                    break;
                case USER:
                    pw.print("    User ");
                    pw.print(bs.userId);
                    pw.print(": ");
                    break;
                case UNACCOUNTED:
                    pw.print("    Unaccounted: ");
                    break;
                case OVERCOUNTED:
                    pw.print("    Over-counted: ");
                    break;
                case CAMERA:
                    pw.print("    Camera: ");
                    break;
                default:
                    pw.print("    ???: ");
                    break;
            }
            printmAh(pw, bs.totalPowerMah);
            if (bs.usagePowerMah != bs.totalPowerMah) {
                // If the usage (generic power) isn't the whole amount, we list out
                // what components are involved in the calculation.
                pw.print(" (");
                if (bs.usagePowerMah != 0) {
                    pw.print(" usage=");
                    printmAh(pw, bs.usagePowerMah);
                }
                if (bs.cpuPowerMah != 0) {
                    pw.print(" cpu=");
                    printmAh(pw, bs.cpuPowerMah);
                }
                if (bs.wakeLockPowerMah != 0) {
                    pw.print(" wake=");
                    printmAh(pw, bs.wakeLockPowerMah);
                }
                if (bs.mobileRadioPowerMah != 0) {
                    pw.print(" radio=");
                    printmAh(pw, bs.mobileRadioPowerMah);
                }
                if (bs.wifiPowerMah != 0) {
                    pw.print(" wifi=");
                    printmAh(pw, bs.wifiPowerMah);
                }
                if (bs.bluetoothPowerMah != 0) {
                    pw.print(" bt=");
                    printmAh(pw, bs.bluetoothPowerMah);
                }
                if (bs.gpsPowerMah != 0) {
                    pw.print(" gps=");
                    printmAh(pw, bs.gpsPowerMah);
                }
                if (bs.sensorPowerMah != 0) {
                    pw.print(" sensor=");
                    printmAh(pw, bs.sensorPowerMah);
                }
                if (bs.cameraPowerMah != 0) {
                    pw.print(" camera=");
                    printmAh(pw, bs.cameraPowerMah);
                }
                if (bs.flashlightPowerMah != 0) {
                    pw.print(" flash=");
                    printmAh(pw, bs.flashlightPowerMah);
                }
                pw.print(" )");
            }
            pw.println();
        }
        pw.println();
    }
    sippers = helper.getMobilemsppList();
    if (sippers != null && sippers.size() > 0) {
        pw.print(prefix);
        pw.println("  Per-app mobile ms per packet:");
        long totalTime = 0;
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Uid ");
            UserHandle.formatUid(sb, bs.uidObj.getUid());
            sb.append(": ");
            sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
            sb.append(" (");
            sb.append(bs.mobileRxPackets + bs.mobileTxPackets);
            sb.append(" packets over ");
            formatTimeMsNoSpace(sb, bs.mobileActive);
            sb.append(") ");
            sb.append(bs.mobileActiveCount);
            sb.append("x");
            pw.println(sb.toString());
            totalTime += bs.mobileActive;
        }
        sb.setLength(0);
        sb.append(prefix);
        sb.append("    TOTAL TIME: ");
        formatTimeMs(sb, totalTime);
        sb.append("(");
        sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
        pw.println();
    }
    final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {

        @Override
        public int compare(TimerEntry lhs, TimerEntry rhs) {
            long lhsTime = lhs.mTime;
            long rhsTime = rhs.mTime;
            if (lhsTime < rhsTime) {
                return 1;
            }
            if (lhsTime > rhsTime) {
                return -1;
            }
            return 0;
        }
    };
    if (reqUid < 0) {
        final Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
        if (kernelWakelocks.size() > 0) {
            final ArrayList<TimerEntry> ktimers = new ArrayList<>();
            for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
                final BatteryStats.Timer timer = ent.getValue();
                final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
                if (totalTimeMillis > 0) {
                    ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
                }
            }
            if (ktimers.size() > 0) {
                Collections.sort(ktimers, timerComparator);
                pw.print(prefix);
                pw.println("  All kernel wake locks:");
                for (int i = 0; i < ktimers.size(); i++) {
                    final TimerEntry timer = ktimers.get(i);
                    String linePrefix = ": ";
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("  Kernel Wake lock ");
                    sb.append(timer.mName);
                    linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, which, linePrefix);
                    if (!linePrefix.equals(": ")) {
                        sb.append(" realtime");
                        // Only print out wake locks that were held
                        pw.println(sb.toString());
                    }
                }
                pw.println();
            }
        }
        if (timers.size() > 0) {
            Collections.sort(timers, timerComparator);
            pw.print(prefix);
            pw.println("  All partial wake locks:");
            for (int i = 0; i < timers.size(); i++) {
                TimerEntry timer = timers.get(i);
                sb.setLength(0);
                sb.append("  Wake lock ");
                UserHandle.formatUid(sb, timer.mId);
                sb.append(" ");
                sb.append(timer.mName);
                printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
                sb.append(" realtime");
                pw.println(sb.toString());
            }
            timers.clear();
            pw.println();
        }
        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
        if (wakeupReasons.size() > 0) {
            pw.print(prefix);
            pw.println("  All wakeup reasons:");
            final ArrayList<TimerEntry> reasons = new ArrayList<>();
            for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
                final Timer timer = ent.getValue();
                reasons.add(new TimerEntry(ent.getKey(), 0, timer, timer.getCountLocked(which)));
            }
            Collections.sort(reasons, timerComparator);
            for (int i = 0; i < reasons.size(); i++) {
                TimerEntry timer = reasons.get(i);
                String linePrefix = ": ";
                sb.setLength(0);
                sb.append(prefix);
                sb.append("  Wakeup reason ");
                sb.append(timer.mName);
                printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
                sb.append(" realtime");
                pw.println(sb.toString());
            }
            pw.println();
        }
    }
    for (int iu = 0; iu < NU; iu++) {
        final int uid = uidStats.keyAt(iu);
        if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
            continue;
        }
        final Uid u = uidStats.valueAt(iu);
        pw.print(prefix);
        pw.print("  ");
        UserHandle.formatUid(pw, uid);
        pw.println(":");
        boolean uidActivity = false;
        final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
        final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
        final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
        final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
        final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
        final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
        final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
        final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
        final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
        final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
        final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
        final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
        final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
        final int wifiScanCount = u.getWifiScanCount(which);
        final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
        final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
        final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
        if (mobileRxBytes > 0 || mobileTxBytes > 0 || mobileRxPackets > 0 || mobileTxPackets > 0) {
            pw.print(prefix);
            pw.print("    Mobile network: ");
            pw.print(formatBytesLocked(mobileRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(mobileTxBytes));
            pw.print(" sent (packets ");
            pw.print(mobileRxPackets);
            pw.print(" received, ");
            pw.print(mobileTxPackets);
            pw.println(" sent)");
        }
        if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Mobile radio active: ");
            formatTimeMs(sb, uidMobileActiveTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
            sb.append(") ");
            sb.append(uidMobileActiveCount);
            sb.append("x");
            long packets = mobileRxPackets + mobileTxPackets;
            if (packets == 0) {
                packets = 1;
            }
            sb.append(" @ ");
            sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double) packets));
            sb.append(" mspp");
            pw.println(sb.toString());
        }
        if (mobileWakeup > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Mobile radio AP wakeups: ");
            sb.append(mobileWakeup);
            pw.println(sb.toString());
        }
        printControllerActivityIfInteresting(pw, sb, prefix + "  ", "Modem", u.getModemControllerActivity(), which);
        if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
            pw.print(prefix);
            pw.print("    Wi-Fi network: ");
            pw.print(formatBytesLocked(wifiRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(wifiTxBytes));
            pw.print(" sent (packets ");
            pw.print(wifiRxPackets);
            pw.print(" received, ");
            pw.print(wifiTxPackets);
            pw.println(" sent)");
        }
        if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 || uidWifiRunningTime != 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Wifi Running: ");
            formatTimeMs(sb, uidWifiRunningTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(uidWifiRunningTime, whichBatteryRealtime));
            sb.append(")\n");
            sb.append(prefix);
            sb.append("    Full Wifi Lock: ");
            formatTimeMs(sb, fullWifiLockOnTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(fullWifiLockOnTime, whichBatteryRealtime));
            sb.append(")\n");
            sb.append(prefix);
            sb.append("    Wifi Scan: ");
            formatTimeMs(sb, wifiScanTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(wifiScanTime, whichBatteryRealtime));
            sb.append(") ");
            sb.append(wifiScanCount);
            sb.append("x");
            pw.println(sb.toString());
        }
        if (wifiWakeup > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    WiFi AP wakeups: ");
            sb.append(wifiWakeup);
            pw.println(sb.toString());
        }
        printControllerActivityIfInteresting(pw, sb, prefix + "  ", "WiFi", u.getWifiControllerActivity(), which);
        if (btRxBytes > 0 || btTxBytes > 0) {
            pw.print(prefix);
            pw.print("    Bluetooth network: ");
            pw.print(formatBytesLocked(btRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(btTxBytes));
            pw.println(" sent");
        }
        uidActivity |= printTimer(pw, sb, u.getBluetoothScanTimer(), rawRealtime, which, prefix, "Bluetooth Scan");
        if (u.hasUserActivity()) {
            boolean hasData = false;
            for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                final int val = u.getUserActivityCount(i, which);
                if (val != 0) {
                    if (!hasData) {
                        sb.setLength(0);
                        sb.append("    User activity: ");
                        hasData = true;
                    } else {
                        sb.append(", ");
                    }
                    sb.append(val);
                    sb.append(" ");
                    sb.append(Uid.USER_ACTIVITY_TYPES[i]);
                }
            }
            if (hasData) {
                pw.println(sb.toString());
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
        long totalDrawWakelock = 0;
        int countWakelock = 0;
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            String linePrefix = ": ";
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Wake lock ");
            sb.append(wakelocks.keyAt(iw));
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "full", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, "partial", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "window", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime, "draw", which, linePrefix);
            sb.append(" realtime");
            pw.println(sb.toString());
            uidActivity = true;
            countWakelock++;
            totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, which);
            totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, which);
            totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, which);
            totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime, which);
        }
        if (countWakelock > 1) {
            if (totalFullWakelock != 0 || totalPartialWakelock != 0 || totalWindowWakelock != 0) {
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    TOTAL wake: ");
                boolean needComma = false;
                if (totalFullWakelock != 0) {
                    needComma = true;
                    formatTimeMs(sb, totalFullWakelock);
                    sb.append("full");
                }
                if (totalPartialWakelock != 0) {
                    if (needComma) {
                        sb.append(", ");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalPartialWakelock);
                    sb.append("partial");
                }
                if (totalWindowWakelock != 0) {
                    if (needComma) {
                        sb.append(", ");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalWindowWakelock);
                    sb.append("window");
                }
                if (totalDrawWakelock != 0) {
                    if (needComma) {
                        sb.append(",");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalDrawWakelock);
                    sb.append("draw");
                }
                sb.append(" realtime");
                pw.println(sb.toString());
            }
        }
        final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
        for (int isy = syncs.size() - 1; isy >= 0; isy--) {
            final Timer timer = syncs.valueAt(isy);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Sync ");
            sb.append(syncs.keyAt(isy));
            sb.append(": ");
            if (totalTime != 0) {
                formatTimeMs(sb, totalTime);
                sb.append("realtime (");
                sb.append(count);
                sb.append(" times)");
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
        for (int ij = jobs.size() - 1; ij >= 0; ij--) {
            final Timer timer = jobs.valueAt(ij);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Job ");
            sb.append(jobs.keyAt(ij));
            sb.append(": ");
            if (totalTime != 0) {
                formatTimeMs(sb, totalTime);
                sb.append("realtime (");
                sb.append(count);
                sb.append(" times)");
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which, prefix, "Flashlight");
        uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which, prefix, "Camera");
        uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which, prefix, "Video");
        uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which, prefix, "Audio");
        final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
        final int NSE = sensors.size();
        for (int ise = 0; ise < NSE; ise++) {
            final Uid.Sensor se = sensors.valueAt(ise);
            final int sensorNumber = sensors.keyAt(ise);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Sensor ");
            int handle = se.getHandle();
            if (handle == Uid.Sensor.GPS) {
                sb.append("GPS");
            } else {
                sb.append(handle);
            }
            sb.append(": ");
            final Timer timer = se.getSensorTime();
            if (timer != null) {
                // Convert from microseconds to milliseconds with rounding
                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final int count = timer.getCountLocked(which);
                //timer.logState();
                if (totalTime != 0) {
                    formatTimeMs(sb, totalTime);
                    sb.append("realtime (");
                    sb.append(count);
                    sb.append(" times)");
                } else {
                    sb.append("(not used)");
                }
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix, "Vibrator");
        uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which, prefix, "Foreground activities");
        long totalStateTime = 0;
        for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ips++) {
            long time = u.getProcessStateTime(ips, rawRealtime, which);
            if (time > 0) {
                totalStateTime += time;
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    ");
                sb.append(Uid.PROCESS_STATE_NAMES[ips]);
                sb.append(" for: ");
                formatTimeMs(sb, (time + 500) / 1000);
                pw.println(sb.toString());
                uidActivity = true;
            }
        }
        if (totalStateTime > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Total running: ");
            formatTimeMs(sb, (totalStateTime + 500) / 1000);
            pw.println(sb.toString());
        }
        final long userCpuTimeUs = u.getUserCpuTimeUs(which);
        final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
        final long powerCpuMaUs = u.getCpuPowerMaUs(which);
        if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Total cpu time: u=");
            formatTimeMs(sb, userCpuTimeUs / 1000);
            sb.append("s=");
            formatTimeMs(sb, systemCpuTimeUs / 1000);
            sb.append("p=");
            printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
            sb.append("mAh");
            pw.println(sb.toString());
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
        for (int ipr = processStats.size() - 1; ipr >= 0; ipr--) {
            final Uid.Proc ps = processStats.valueAt(ipr);
            long userTime;
            long systemTime;
            long foregroundTime;
            int starts;
            int numExcessive;
            userTime = ps.getUserTime(which);
            systemTime = ps.getSystemTime(which);
            foregroundTime = ps.getForegroundTime(which);
            starts = ps.getStarts(which);
            final int numCrashes = ps.getNumCrashes(which);
            final int numAnrs = ps.getNumAnrs(which);
            numExcessive = which == STATS_SINCE_CHARGED ? ps.countExcessivePowers() : 0;
            if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    Proc ");
                sb.append(processStats.keyAt(ipr));
                sb.append(":\n");
                sb.append(prefix);
                sb.append("      CPU: ");
                formatTimeMs(sb, userTime);
                sb.append("usr + ");
                formatTimeMs(sb, systemTime);
                sb.append("krn ; ");
                formatTimeMs(sb, foregroundTime);
                sb.append("fg");
                if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
                    sb.append("\n");
                    sb.append(prefix);
                    sb.append("      ");
                    boolean hasOne = false;
                    if (starts != 0) {
                        hasOne = true;
                        sb.append(starts);
                        sb.append(" starts");
                    }
                    if (numCrashes != 0) {
                        if (hasOne) {
                            sb.append(", ");
                        }
                        hasOne = true;
                        sb.append(numCrashes);
                        sb.append(" crashes");
                    }
                    if (numAnrs != 0) {
                        if (hasOne) {
                            sb.append(", ");
                        }
                        sb.append(numAnrs);
                        sb.append(" anrs");
                    }
                }
                pw.println(sb.toString());
                for (int e = 0; e < numExcessive; e++) {
                    Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
                    if (ew != null) {
                        pw.print(prefix);
                        pw.print("      * Killed for ");
                        if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
                            pw.print("wake lock");
                        } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
                            pw.print("cpu");
                        } else {
                            pw.print("unknown");
                        }
                        pw.print(" use: ");
                        TimeUtils.formatDuration(ew.usedTime, pw);
                        pw.print(" over ");
                        TimeUtils.formatDuration(ew.overTime, pw);
                        if (ew.overTime != 0) {
                            pw.print(" (");
                            pw.print((ew.usedTime * 100) / ew.overTime);
                            pw.println("%)");
                        }
                    }
                }
                uidActivity = true;
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            pw.print(prefix);
            pw.print("    Apk ");
            pw.print(packageStats.keyAt(ipkg));
            pw.println(":");
            boolean apkActivity = false;
            final Uid.Pkg ps = packageStats.valueAt(ipkg);
            final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                pw.print(prefix);
                pw.print("      Wakeup alarm ");
                pw.print(alarms.keyAt(iwa));
                pw.print(": ");
                pw.print(alarms.valueAt(iwa).getCountLocked(which));
                pw.println(" times");
                apkActivity = true;
            }
            final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
            for (int isvc = serviceStats.size() - 1; isvc >= 0; isvc--) {
                final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
                final long startTime = ss.getStartTime(batteryUptime, which);
                final int starts = ss.getStarts(which);
                final int launches = ss.getLaunches(which);
                if (startTime != 0 || starts != 0 || launches != 0) {
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("      Service ");
                    sb.append(serviceStats.keyAt(isvc));
                    sb.append(":\n");
                    sb.append(prefix);
                    sb.append("        Created for: ");
                    formatTimeMs(sb, startTime / 1000);
                    sb.append("uptime\n");
                    sb.append(prefix);
                    sb.append("        Starts: ");
                    sb.append(starts);
                    sb.append(", launches: ");
                    sb.append(launches);
                    pw.println(sb.toString());
                    apkActivity = true;
                }
            }
            if (!apkActivity) {
                pw.print(prefix);
                pw.println("      (nothing executed)");
            }
            uidActivity = true;
        }
        if (!uidActivity) {
            pw.print(prefix);
            pw.println("    (nothing executed)");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Comparator(java.util.Comparator) BatterySipper(com.android.internal.os.BatterySipper) BatteryStatsHelper(com.android.internal.os.BatteryStatsHelper) HashMap(java.util.HashMap) Map(java.util.Map) ArrayMap(android.util.ArrayMap)

Example 9 with BatterySipper

use of com.android.internal.os.BatterySipper in project platform_frameworks_base by android.

the class BatteryStats method dumpCheckinLocked.

/**
     * Checkin server version of dump to produce more compact, computer-readable log.
     * 
     * NOTE: all times are expressed in 'ms'.
     */
public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly) {
    final long rawUptime = SystemClock.uptimeMillis() * 1000;
    final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
    final long batteryUptime = getBatteryUptime(rawUptime);
    final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
    final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
    final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
    final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, which);
    final long totalRealtime = computeRealtime(rawRealtime, which);
    final long totalUptime = computeUptime(rawUptime, which);
    final long screenOnTime = getScreenOnTime(rawRealtime, which);
    final long interactiveTime = getInteractiveTime(rawRealtime, which);
    final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
    final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final int connChanges = getNumConnectivityChange(which);
    final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
    final long dischargeCount = getDischargeCoulombCounter().getCountLocked(which);
    final long dischargeScreenOffCount = getDischargeScreenOffCoulombCounter().getCountLocked(which);
    final StringBuilder sb = new StringBuilder(128);
    final SparseArray<? extends Uid> uidStats = getUidStats();
    final int NU = uidStats.size();
    final String category = STAT_NAMES[which];
    // Dump "battery" stat
    dumpLine(pw, 0, /* uid */
    category, BATTERY_DATA, which == STATS_SINCE_CHARGED ? getStartCount() : "N/A", whichBatteryRealtime / 1000, whichBatteryUptime / 1000, totalRealtime / 1000, totalUptime / 1000, getStartClockTime(), whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000, getEstimatedBatteryCapacity());
    // Calculate wakelock times across all uids.
    long fullWakeLockTimeTotal = 0;
    long partialWakeLockTimeTotal = 0;
    for (int iu = 0; iu < NU; iu++) {
        final Uid u = uidStats.valueAt(iu);
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
            if (fullWakeTimer != null) {
                fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
            final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
            if (partialWakeTimer != null) {
                partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
        }
    }
    // Dump network stats
    final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
    final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
    final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
    final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_NETWORK_DATA, mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets, btRxTotalBytes, btTxTotalBytes);
    // Dump Modem controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_MODEM_CONTROLLER_DATA, getModemControllerActivity(), which);
    // Dump Wifi controller stats
    final long wifiOnTime = getWifiOnTime(rawRealtime, which);
    final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
    dumpLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_DATA, wifiOnTime / 1000, wifiRunningTime / 1000, /* legacy fields follow, keep at 0 */
    0, 0, 0);
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_WIFI_CONTROLLER_DATA, getWifiControllerActivity(), which);
    // Dump Bluetooth controller stats
    dumpControllerActivityLine(pw, 0, /* uid */
    category, GLOBAL_BLUETOOTH_CONTROLLER_DATA, getBluetoothControllerActivity(), which);
    // Dump misc stats
    dumpLine(pw, 0, /* uid */
    category, MISC_DATA, screenOnTime / 1000, phoneOnTime / 1000, fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000, getMobileRadioActiveTime(rawRealtime, which) / 1000, getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeFullTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which), deviceIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which), getMobileRadioActiveCount(which), getMobileRadioActiveUnknownTime(which) / 1000, deviceIdleModeLightTime / 1000, getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which), deviceLightIdlingTime / 1000, getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT), getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
    // Dump screen brightness stats
    Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
    for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
        args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SCREEN_BRIGHTNESS_DATA, args);
    // Dump signal strength stats
    args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_TIME_DATA, args);
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_SCANNING_TIME_DATA, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getPhoneSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, SIGNAL_STRENGTH_COUNT_DATA, args);
    // Dump network type stats
    args = new Object[NUM_DATA_CONNECTION_TYPES];
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_TIME_DATA, args);
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        args[i] = getPhoneDataConnectionCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, DATA_CONNECTION_COUNT_DATA, args);
    // Dump wifi state stats
    args = new Object[NUM_WIFI_STATES];
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        args[i] = getWifiStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_STATE_COUNT_DATA, args);
    // Dump wifi suppl state stats
    args = new Object[NUM_WIFI_SUPPL_STATES];
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        args[i] = getWifiSupplStateCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SUPPL_STATE_COUNT_DATA, args);
    // Dump wifi signal strength stats
    args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        args[i] = getWifiSignalStrengthCount(i, which);
    }
    dumpLine(pw, 0, /* uid */
    category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), getDischargeCurrentLevel());
    }
    if (which == STATS_SINCE_UNPLUGGED) {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeStartLevel() - getDischargeCurrentLevel(), getDischargeAmountScreenOn(), getDischargeAmountScreenOff(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    } else {
        dumpLine(pw, 0, /* uid */
        category, BATTERY_DISCHARGE_DATA, getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), getDischargeAmountScreenOnSinceCharge(), getDischargeAmountScreenOffSinceCharge(), dischargeCount / 1000, dischargeScreenOffCount / 1000);
    }
    if (reqUid < 0) {
        final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
        if (kernelWakelocks.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
                sb.setLength(0);
                printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
                dumpLine(pw, 0, /* uid */
                category, KERNEL_WAKELOCK_DATA, ent.getKey(), sb.toString());
            }
        }
        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
        if (wakeupReasons.size() > 0) {
            for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
                // Not doing the regular wake lock formatting to remain compatible
                // with the old checkin format.
                long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
                int count = ent.getValue().getCountLocked(which);
                dumpLine(pw, 0, /* uid */
                category, WAKEUP_REASON_DATA, "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
            }
        }
    }
    final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
    helper.create(this);
    helper.refreshStats(which, UserHandle.USER_ALL);
    final List<BatterySipper> sippers = helper.getUsageList();
    if (sippers != null && sippers.size() > 0) {
        dumpLine(pw, 0, /* uid */
        category, POWER_USE_SUMMARY_DATA, BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()), BatteryStatsHelper.makemAh(helper.getComputedPower()), BatteryStatsHelper.makemAh(helper.getMinDrainedPower()), BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            int uid = 0;
            String label;
            switch(bs.drainType) {
                case IDLE:
                    label = "idle";
                    break;
                case CELL:
                    label = "cell";
                    break;
                case PHONE:
                    label = "phone";
                    break;
                case WIFI:
                    label = "wifi";
                    break;
                case BLUETOOTH:
                    label = "blue";
                    break;
                case SCREEN:
                    label = "scrn";
                    break;
                case FLASHLIGHT:
                    label = "flashlight";
                    break;
                case APP:
                    uid = bs.uidObj.getUid();
                    label = "uid";
                    break;
                case USER:
                    uid = UserHandle.getUid(bs.userId, 0);
                    label = "user";
                    break;
                case UNACCOUNTED:
                    label = "unacc";
                    break;
                case OVERCOUNTED:
                    label = "over";
                    break;
                case CAMERA:
                    label = "camera";
                    break;
                default:
                    label = "???";
            }
            dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, BatteryStatsHelper.makemAh(bs.totalPowerMah));
        }
    }
    for (int iu = 0; iu < NU; iu++) {
        final int uid = uidStats.keyAt(iu);
        if (reqUid >= 0 && uid != reqUid) {
            continue;
        }
        final Uid u = uidStats.valueAt(iu);
        // Dump Network stats per uid, if any
        final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
        final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
        final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
        final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
        final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
        final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
        final long mobileActiveTime = u.getMobileRadioActiveTime(which);
        final int mobileActiveCount = u.getMobileRadioActiveCount(which);
        final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
        final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
        final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
        final long btBytesRx = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
        final long btBytesTx = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
        if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0 || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0 || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0 || btBytesRx > 0 || btBytesTx > 0 || mobileWakeup > 0 || wifiWakeup > 0) {
            dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx, wifiBytesRx, wifiBytesTx, mobilePacketsRx, mobilePacketsTx, wifiPacketsRx, wifiPacketsTx, mobileActiveTime, mobileActiveCount, btBytesRx, btBytesTx, mobileWakeup, wifiWakeup);
        }
        // Dump modem controller data, per UID.
        dumpControllerActivityLine(pw, uid, category, MODEM_CONTROLLER_DATA, u.getModemControllerActivity(), which);
        // Dump Wifi controller data, per UID.
        final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
        final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
        final int wifiScanCount = u.getWifiScanCount(which);
        final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
        if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 || uidWifiRunningTime != 0) {
            dumpLine(pw, uid, category, WIFI_DATA, fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime, wifiScanCount, /* legacy fields follow, keep at 0 */
            0, 0, 0);
        }
        dumpControllerActivityLine(pw, uid, category, WIFI_CONTROLLER_DATA, u.getWifiControllerActivity(), which);
        dumpTimer(pw, uid, category, BLUETOOTH_MISC_DATA, u.getBluetoothScanTimer(), rawRealtime, which);
        dumpControllerActivityLine(pw, uid, category, BLUETOOTH_CONTROLLER_DATA, u.getBluetoothControllerActivity(), which);
        if (u.hasUserActivity()) {
            args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
            boolean hasData = false;
            for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                int val = u.getUserActivityCount(i, which);
                args[i] = val;
                if (val != 0)
                    hasData = true;
            }
            if (hasData) {
                dumpLine(pw, uid, /* uid */
                category, USER_ACTIVITY_DATA, args);
            }
        }
        final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            String linePrefix = "";
            sb.setLength(0);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "f", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, "p", which, linePrefix);
            linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "w", which, linePrefix);
            // Only log if we had at lease one wakelock...
            if (sb.length() > 0) {
                String name = wakelocks.keyAt(iw);
                if (name.indexOf(',') >= 0) {
                    name = name.replace(',', '_');
                }
                dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
            }
        }
        final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
        for (int isy = syncs.size() - 1; isy >= 0; isy--) {
            final Timer timer = syncs.valueAt(isy);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
            }
        }
        final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
        for (int ij = jobs.size() - 1; ij >= 0; ij--) {
            final Timer timer = jobs.valueAt(ij);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            if (totalTime != 0) {
                dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
            }
        }
        dumpTimer(pw, uid, category, FLASHLIGHT_DATA, u.getFlashlightTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, CAMERA_DATA, u.getCameraTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, VIDEO_DATA, u.getVideoTurnedOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, AUDIO_DATA, u.getAudioTurnedOnTimer(), rawRealtime, which);
        final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
        final int NSE = sensors.size();
        for (int ise = 0; ise < NSE; ise++) {
            final Uid.Sensor se = sensors.valueAt(ise);
            final int sensorNumber = sensors.keyAt(ise);
            final Timer timer = se.getSensorTime();
            if (timer != null) {
                // Convert from microseconds to milliseconds with rounding
                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final int count = timer.getCountLocked(which);
                if (totalTime != 0) {
                    dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
                }
            }
        }
        dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(), rawRealtime, which);
        dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(), rawRealtime, which);
        final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
        long totalStateTime = 0;
        for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ips++) {
            final long time = u.getProcessStateTime(ips, rawRealtime, which);
            totalStateTime += time;
            stateTimes[ips] = (time + 500) / 1000;
        }
        if (totalStateTime > 0) {
            dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
        }
        final long userCpuTimeUs = u.getUserCpuTimeUs(which);
        final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
        final long powerCpuMaUs = u.getCpuPowerMaUs(which);
        if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
            dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000, powerCpuMaUs / 1000);
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
        for (int ipr = processStats.size() - 1; ipr >= 0; ipr--) {
            final Uid.Proc ps = processStats.valueAt(ipr);
            final long userMillis = ps.getUserTime(which);
            final long systemMillis = ps.getSystemTime(which);
            final long foregroundMillis = ps.getForegroundTime(which);
            final int starts = ps.getStarts(which);
            final int numCrashes = ps.getNumCrashes(which);
            final int numAnrs = ps.getNumAnrs(which);
            if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0 || starts != 0 || numAnrs != 0 || numCrashes != 0) {
                dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis, systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            final Uid.Pkg ps = packageStats.valueAt(ipkg);
            int wakeups = 0;
            final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                int count = alarms.valueAt(iwa).getCountLocked(which);
                wakeups += count;
                String name = alarms.keyAt(iwa).replace(',', '_');
                dumpLine(pw, uid, category, WAKEUP_ALARM_DATA, name, count);
            }
            final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
            for (int isvc = serviceStats.size() - 1; isvc >= 0; isvc--) {
                final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
                final long startTime = ss.getStartTime(batteryUptime, which);
                final int starts = ss.getStarts(which);
                final int launches = ss.getLaunches(which);
                if (startTime != 0 || starts != 0 || launches != 0) {
                    dumpLine(pw, uid, category, APK_DATA, // wakeup alarms
                    wakeups, // Apk
                    packageStats.keyAt(ipkg), // service
                    serviceStats.keyAt(isvc), // time spent started, in ms
                    startTime / 1000, starts, launches);
                }
            }
        }
    }
}
Also used : BatterySipper(com.android.internal.os.BatterySipper) HashMap(java.util.HashMap) Map(java.util.Map) ArrayMap(android.util.ArrayMap) BatteryStatsHelper(com.android.internal.os.BatteryStatsHelper)

Example 10 with BatterySipper

use of com.android.internal.os.BatterySipper in project android_frameworks_base by DirtyUnicorns.

the class BatteryStats method dumpLocked.

@SuppressWarnings("unused")
public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which, int reqUid, boolean wifiOnly) {
    final long rawUptime = SystemClock.uptimeMillis() * 1000;
    final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
    final long batteryUptime = getBatteryUptime(rawUptime);
    final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
    final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
    final long totalRealtime = computeRealtime(rawRealtime, which);
    final long totalUptime = computeUptime(rawUptime, which);
    final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
    final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime, which);
    final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
    final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
    final StringBuilder sb = new StringBuilder(128);
    final SparseArray<? extends Uid> uidStats = getUidStats();
    final int NU = uidStats.size();
    final int estimatedBatteryCapacity = getEstimatedBatteryCapacity();
    if (estimatedBatteryCapacity > 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Estimated battery capacity: ");
        sb.append(BatteryStatsHelper.makemAh(estimatedBatteryCapacity));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Time on battery: ");
    formatTimeMs(sb, whichBatteryRealtime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
    sb.append(") realtime, ");
    formatTimeMs(sb, whichBatteryUptime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
    sb.append(") uptime");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Time on battery screen off: ");
    formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
    sb.append(") realtime, ");
    formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
    sb.append(") uptime");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Total run time: ");
    formatTimeMs(sb, totalRealtime / 1000);
    sb.append("realtime, ");
    formatTimeMs(sb, totalUptime / 1000);
    sb.append("uptime");
    pw.println(sb.toString());
    if (batteryTimeRemaining >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Battery time remaining: ");
        formatTimeMs(sb, batteryTimeRemaining / 1000);
        pw.println(sb.toString());
    }
    if (chargeTimeRemaining >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Charge time remaining: ");
        formatTimeMs(sb, chargeTimeRemaining / 1000);
        pw.println(sb.toString());
    }
    final LongCounter dischargeCounter = getDischargeCoulombCounter();
    final long dischargeCount = dischargeCounter.getCountLocked(which);
    if (dischargeCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    final LongCounter dischargeScreenOffCounter = getDischargeScreenOffCoulombCounter();
    final long dischargeScreenOffCount = dischargeScreenOffCounter.getCountLocked(which);
    if (dischargeScreenOffCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Screen off discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeScreenOffCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    final long dischargeScreenOnCount = dischargeCount - dischargeScreenOffCount;
    if (dischargeScreenOnCount >= 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Screen on discharge: ");
        sb.append(BatteryStatsHelper.makemAh(dischargeScreenOnCount / 1000.0));
        sb.append(" mAh");
        pw.println(sb.toString());
    }
    pw.print("  Start clock time: ");
    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
    final long screenOnTime = getScreenOnTime(rawRealtime, which);
    final long interactiveTime = getInteractiveTime(rawRealtime, which);
    final long powerSaveModeEnabledTime = getPowerSaveModeEnabledTime(rawRealtime, which);
    final long deviceIdleModeLightTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdleModeFullTime = getDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long deviceLightIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_LIGHT, rawRealtime, which);
    final long deviceIdlingTime = getDeviceIdlingTime(DEVICE_IDLE_MODE_DEEP, rawRealtime, which);
    final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
    final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
    final long wifiOnTime = getWifiOnTime(rawRealtime, which);
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Screen on: ");
    formatTimeMs(sb, screenOnTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
    sb.append(") ");
    sb.append(getScreenOnCount(which));
    sb.append("x, Interactive: ");
    formatTimeMs(sb, interactiveTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
    sb.append(")");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Screen brightnesses:");
    boolean didOne = false;
    for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
        final long time = getScreenBrightnessTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, screenOnTime));
        sb.append(")");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    if (powerSaveModeEnabledTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Power save mode enabled: ");
        formatTimeMs(sb, powerSaveModeEnabledTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(powerSaveModeEnabledTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
    }
    if (deviceLightIdlingTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Device light idling: ");
        formatTimeMs(sb, deviceLightIdlingTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceLightIdlingTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which));
        sb.append("x");
        pw.println(sb.toString());
    }
    if (deviceIdleModeLightTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Idle mode light time: ");
        formatTimeMs(sb, deviceIdleModeLightTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdleModeLightTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_LIGHT, which));
        sb.append("x");
        sb.append(" -- longest ");
        formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
        pw.println(sb.toString());
    }
    if (deviceIdlingTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Device full idling: ");
        formatTimeMs(sb, deviceIdlingTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdlingTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdlingCount(DEVICE_IDLE_MODE_DEEP, which));
        sb.append("x");
        pw.println(sb.toString());
    }
    if (deviceIdleModeFullTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Idle mode full time: ");
        formatTimeMs(sb, deviceIdleModeFullTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(deviceIdleModeFullTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getDeviceIdleModeCount(DEVICE_IDLE_MODE_DEEP, which));
        sb.append("x");
        sb.append(" -- longest ");
        formatTimeMs(sb, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
        pw.println(sb.toString());
    }
    if (phoneOnTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Active phone call: ");
        formatTimeMs(sb, phoneOnTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneOnCount(which));
        sb.append("x");
    }
    final int connChanges = getNumConnectivityChange(which);
    if (connChanges != 0) {
        pw.print(prefix);
        pw.print("  Connectivity changes: ");
        pw.println(connChanges);
    }
    // Calculate wakelock times across all uids.
    long fullWakeLockTimeTotalMicros = 0;
    long partialWakeLockTimeTotalMicros = 0;
    final ArrayList<TimerEntry> timers = new ArrayList<>();
    for (int iu = 0; iu < NU; iu++) {
        final Uid u = uidStats.valueAt(iu);
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
            if (fullWakeTimer != null) {
                fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(rawRealtime, which);
            }
            final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
            if (partialWakeTimer != null) {
                final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(rawRealtime, which);
                if (totalTimeMicros > 0) {
                    if (reqUid < 0) {
                        // Only show the ordered list of all wake
                        // locks if the caller is not asking for data
                        // about a specific uid.
                        timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(), partialWakeTimer, totalTimeMicros));
                    }
                    partialWakeLockTimeTotalMicros += totalTimeMicros;
                }
            }
        }
    }
    final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
    final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
    final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
    final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
    final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
    final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
    final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
    if (fullWakeLockTimeTotalMicros != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Total full wakelock time: ");
        formatTimeMsNoSpace(sb, (fullWakeLockTimeTotalMicros + 500) / 1000);
        pw.println(sb.toString());
    }
    if (partialWakeLockTimeTotalMicros != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Total partial wakelock time: ");
        formatTimeMsNoSpace(sb, (partialWakeLockTimeTotalMicros + 500) / 1000);
        pw.println(sb.toString());
    }
    pw.print(prefix);
    pw.print("  Mobile total received: ");
    pw.print(formatBytesLocked(mobileRxTotalBytes));
    pw.print(", sent: ");
    pw.print(formatBytesLocked(mobileTxTotalBytes));
    pw.print(" (packets received ");
    pw.print(mobileRxTotalPackets);
    pw.print(", sent ");
    pw.print(mobileTxTotalPackets);
    pw.println(")");
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Phone signal levels:");
    didOne = false;
    for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
        final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneSignalStrengthCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Signal scanning time: ");
    formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Radio types:");
    didOne = false;
    for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) {
        final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append(DATA_CONNECTION_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getPhoneDataConnectionCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Mobile radio active time: ");
    final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
    formatTimeMs(sb, mobileActiveTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
    sb.append(") ");
    sb.append(getMobileRadioActiveCount(which));
    sb.append("x");
    pw.println(sb.toString());
    final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
    if (mobileActiveUnknownTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Mobile radio active unknown time: ");
        formatTimeMs(sb, mobileActiveUnknownTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getMobileRadioActiveUnknownCount(which));
        sb.append("x");
        pw.println(sb.toString());
    }
    final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
    if (mobileActiveAdjustedTime != 0) {
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Mobile radio active adjusted time: ");
        formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
    }
    printControllerActivity(pw, sb, prefix, "Radio", getModemControllerActivity(), which);
    pw.print(prefix);
    pw.print("  Wi-Fi total received: ");
    pw.print(formatBytesLocked(wifiRxTotalBytes));
    pw.print(", sent: ");
    pw.print(formatBytesLocked(wifiTxTotalBytes));
    pw.print(" (packets received ");
    pw.print(wifiRxTotalPackets);
    pw.print(", sent ");
    pw.print(wifiTxTotalPackets);
    pw.println(")");
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi on: ");
    formatTimeMs(sb, wifiOnTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
    sb.append("), Wifi running: ");
    formatTimeMs(sb, wifiRunningTime / 1000);
    sb.append("(");
    sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
    sb.append(")");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi states:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_STATES; i++) {
        final long time = getWifiStateTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        didOne = true;
        sb.append(WIFI_STATE_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiStateCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi supplicant states:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) {
        final long time = getWifiSupplStateTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        didOne = true;
        sb.append(WIFI_SUPPL_STATE_NAMES[i]);
        sb.append(" ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiSupplStateCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Wifi signal levels:");
    didOne = false;
    for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
        final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
        if (time == 0) {
            continue;
        }
        sb.append("\n    ");
        sb.append(prefix);
        didOne = true;
        sb.append("level(");
        sb.append(i);
        sb.append(") ");
        formatTimeMs(sb, time / 1000);
        sb.append("(");
        sb.append(formatRatioLocked(time, whichBatteryRealtime));
        sb.append(") ");
        sb.append(getWifiSignalStrengthCount(i, which));
        sb.append("x");
    }
    if (!didOne)
        sb.append(" (no activity)");
    pw.println(sb.toString());
    printControllerActivity(pw, sb, prefix, "WiFi", getWifiControllerActivity(), which);
    pw.print(prefix);
    pw.print("  Bluetooth total received: ");
    pw.print(formatBytesLocked(btRxTotalBytes));
    pw.print(", sent: ");
    pw.println(formatBytesLocked(btTxTotalBytes));
    final long bluetoothScanTimeMs = getBluetoothScanTime(rawRealtime, which) / 1000;
    sb.setLength(0);
    sb.append(prefix);
    sb.append("  Bluetooth scan time: ");
    formatTimeMs(sb, bluetoothScanTimeMs);
    pw.println(sb.toString());
    printControllerActivity(pw, sb, prefix, "Bluetooth", getBluetoothControllerActivity(), which);
    pw.println();
    if (which == STATS_SINCE_UNPLUGGED) {
        if (getIsOnBattery()) {
            pw.print(prefix);
            pw.println("  Device is currently unplugged");
            pw.print(prefix);
            pw.print("    Discharge cycle start level: ");
            pw.println(getDischargeStartLevel());
            pw.print(prefix);
            pw.print("    Discharge cycle current level: ");
            pw.println(getDischargeCurrentLevel());
        } else {
            pw.print(prefix);
            pw.println("  Device is currently plugged into power");
            pw.print(prefix);
            pw.print("    Last discharge cycle start level: ");
            pw.println(getDischargeStartLevel());
            pw.print(prefix);
            pw.print("    Last discharge cycle end level: ");
            pw.println(getDischargeCurrentLevel());
        }
        pw.print(prefix);
        pw.print("    Amount discharged while screen on: ");
        pw.println(getDischargeAmountScreenOn());
        pw.print(prefix);
        pw.print("    Amount discharged while screen off: ");
        pw.println(getDischargeAmountScreenOff());
        pw.println(" ");
    } else {
        pw.print(prefix);
        pw.println("  Device battery use since last full charge");
        pw.print(prefix);
        pw.print("    Amount discharged (lower bound): ");
        pw.println(getLowDischargeAmountSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged (upper bound): ");
        pw.println(getHighDischargeAmountSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged while screen on: ");
        pw.println(getDischargeAmountScreenOnSinceCharge());
        pw.print(prefix);
        pw.print("    Amount discharged while screen off: ");
        pw.println(getDischargeAmountScreenOffSinceCharge());
        pw.println();
    }
    final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
    helper.create(this);
    helper.refreshStats(which, UserHandle.USER_ALL);
    List<BatterySipper> sippers = helper.getUsageList();
    if (sippers != null && sippers.size() > 0) {
        pw.print(prefix);
        pw.println("  Estimated power use (mAh):");
        pw.print(prefix);
        pw.print("    Capacity: ");
        printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
        pw.print(", Computed drain: ");
        printmAh(pw, helper.getComputedPower());
        pw.print(", actual drain: ");
        printmAh(pw, helper.getMinDrainedPower());
        if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
            pw.print("-");
            printmAh(pw, helper.getMaxDrainedPower());
        }
        pw.println();
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            pw.print(prefix);
            switch(bs.drainType) {
                case IDLE:
                    pw.print("    Idle: ");
                    break;
                case CELL:
                    pw.print("    Cell standby: ");
                    break;
                case PHONE:
                    pw.print("    Phone calls: ");
                    break;
                case WIFI:
                    pw.print("    Wifi: ");
                    break;
                case BLUETOOTH:
                    pw.print("    Bluetooth: ");
                    break;
                case SCREEN:
                    pw.print("    Screen: ");
                    break;
                case FLASHLIGHT:
                    pw.print("    Flashlight: ");
                    break;
                case APP:
                    pw.print("    Uid ");
                    UserHandle.formatUid(pw, bs.uidObj.getUid());
                    pw.print(": ");
                    break;
                case USER:
                    pw.print("    User ");
                    pw.print(bs.userId);
                    pw.print(": ");
                    break;
                case UNACCOUNTED:
                    pw.print("    Unaccounted: ");
                    break;
                case OVERCOUNTED:
                    pw.print("    Over-counted: ");
                    break;
                case CAMERA:
                    pw.print("    Camera: ");
                    break;
                default:
                    pw.print("    ???: ");
                    break;
            }
            printmAh(pw, bs.totalPowerMah);
            if (bs.usagePowerMah != bs.totalPowerMah) {
                // If the usage (generic power) isn't the whole amount, we list out
                // what components are involved in the calculation.
                pw.print(" (");
                if (bs.usagePowerMah != 0) {
                    pw.print(" usage=");
                    printmAh(pw, bs.usagePowerMah);
                }
                if (bs.cpuPowerMah != 0) {
                    pw.print(" cpu=");
                    printmAh(pw, bs.cpuPowerMah);
                }
                if (bs.wakeLockPowerMah != 0) {
                    pw.print(" wake=");
                    printmAh(pw, bs.wakeLockPowerMah);
                }
                if (bs.mobileRadioPowerMah != 0) {
                    pw.print(" radio=");
                    printmAh(pw, bs.mobileRadioPowerMah);
                }
                if (bs.wifiPowerMah != 0) {
                    pw.print(" wifi=");
                    printmAh(pw, bs.wifiPowerMah);
                }
                if (bs.bluetoothPowerMah != 0) {
                    pw.print(" bt=");
                    printmAh(pw, bs.bluetoothPowerMah);
                }
                if (bs.gpsPowerMah != 0) {
                    pw.print(" gps=");
                    printmAh(pw, bs.gpsPowerMah);
                }
                if (bs.sensorPowerMah != 0) {
                    pw.print(" sensor=");
                    printmAh(pw, bs.sensorPowerMah);
                }
                if (bs.cameraPowerMah != 0) {
                    pw.print(" camera=");
                    printmAh(pw, bs.cameraPowerMah);
                }
                if (bs.flashlightPowerMah != 0) {
                    pw.print(" flash=");
                    printmAh(pw, bs.flashlightPowerMah);
                }
                pw.print(" )");
            }
            pw.println();
        }
        pw.println();
    }
    sippers = helper.getMobilemsppList();
    if (sippers != null && sippers.size() > 0) {
        pw.print(prefix);
        pw.println("  Per-app mobile ms per packet:");
        long totalTime = 0;
        for (int i = 0; i < sippers.size(); i++) {
            final BatterySipper bs = sippers.get(i);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Uid ");
            UserHandle.formatUid(sb, bs.uidObj.getUid());
            sb.append(": ");
            sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
            sb.append(" (");
            sb.append(bs.mobileRxPackets + bs.mobileTxPackets);
            sb.append(" packets over ");
            formatTimeMsNoSpace(sb, bs.mobileActive);
            sb.append(") ");
            sb.append(bs.mobileActiveCount);
            sb.append("x");
            pw.println(sb.toString());
            totalTime += bs.mobileActive;
        }
        sb.setLength(0);
        sb.append(prefix);
        sb.append("    TOTAL TIME: ");
        formatTimeMs(sb, totalTime);
        sb.append("(");
        sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
        sb.append(")");
        pw.println(sb.toString());
        pw.println();
    }
    final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {

        @Override
        public int compare(TimerEntry lhs, TimerEntry rhs) {
            long lhsTime = lhs.mTime;
            long rhsTime = rhs.mTime;
            if (lhsTime < rhsTime) {
                return 1;
            }
            if (lhsTime > rhsTime) {
                return -1;
            }
            return 0;
        }
    };
    if (reqUid < 0) {
        final Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
        if (kernelWakelocks.size() > 0) {
            final ArrayList<TimerEntry> ktimers = new ArrayList<>();
            for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
                final BatteryStats.Timer timer = ent.getValue();
                final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
                if (totalTimeMillis > 0) {
                    ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
                }
            }
            if (ktimers.size() > 0) {
                Collections.sort(ktimers, timerComparator);
                pw.print(prefix);
                pw.println("  All kernel wake locks:");
                for (int i = 0; i < ktimers.size(); i++) {
                    final TimerEntry timer = ktimers.get(i);
                    String linePrefix = ": ";
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("  Kernel Wake lock ");
                    sb.append(timer.mName);
                    linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null, which, linePrefix);
                    if (!linePrefix.equals(": ")) {
                        sb.append(" realtime");
                        // Only print out wake locks that were held
                        pw.println(sb.toString());
                    }
                }
                pw.println();
            }
        }
        if (timers.size() > 0) {
            Collections.sort(timers, timerComparator);
            pw.print(prefix);
            pw.println("  All partial wake locks:");
            for (int i = 0; i < timers.size(); i++) {
                TimerEntry timer = timers.get(i);
                sb.setLength(0);
                sb.append("  Wake lock ");
                UserHandle.formatUid(sb, timer.mId);
                sb.append(" ");
                sb.append(timer.mName);
                printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
                sb.append(" realtime");
                pw.println(sb.toString());
            }
            timers.clear();
            pw.println();
        }
        final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
        if (wakeupReasons.size() > 0) {
            pw.print(prefix);
            pw.println("  All wakeup reasons:");
            final ArrayList<TimerEntry> reasons = new ArrayList<>();
            for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
                final Timer timer = ent.getValue();
                reasons.add(new TimerEntry(ent.getKey(), 0, timer, timer.getCountLocked(which)));
            }
            Collections.sort(reasons, timerComparator);
            for (int i = 0; i < reasons.size(); i++) {
                TimerEntry timer = reasons.get(i);
                String linePrefix = ": ";
                sb.setLength(0);
                sb.append(prefix);
                sb.append("  Wakeup reason ");
                sb.append(timer.mName);
                printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
                sb.append(" realtime");
                pw.println(sb.toString());
            }
            pw.println();
        }
    }
    for (int iu = 0; iu < NU; iu++) {
        final int uid = uidStats.keyAt(iu);
        if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
            continue;
        }
        final Uid u = uidStats.valueAt(iu);
        pw.print(prefix);
        pw.print("  ");
        UserHandle.formatUid(pw, uid);
        pw.println(":");
        boolean uidActivity = false;
        final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
        final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
        final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
        final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
        final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
        final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
        final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
        final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
        final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
        final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
        final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
        final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
        final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
        final int wifiScanCount = u.getWifiScanCount(which);
        final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
        final long mobileWakeup = u.getMobileRadioApWakeupCount(which);
        final long wifiWakeup = u.getWifiRadioApWakeupCount(which);
        if (mobileRxBytes > 0 || mobileTxBytes > 0 || mobileRxPackets > 0 || mobileTxPackets > 0) {
            pw.print(prefix);
            pw.print("    Mobile network: ");
            pw.print(formatBytesLocked(mobileRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(mobileTxBytes));
            pw.print(" sent (packets ");
            pw.print(mobileRxPackets);
            pw.print(" received, ");
            pw.print(mobileTxPackets);
            pw.println(" sent)");
        }
        if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Mobile radio active: ");
            formatTimeMs(sb, uidMobileActiveTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
            sb.append(") ");
            sb.append(uidMobileActiveCount);
            sb.append("x");
            long packets = mobileRxPackets + mobileTxPackets;
            if (packets == 0) {
                packets = 1;
            }
            sb.append(" @ ");
            sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double) packets));
            sb.append(" mspp");
            pw.println(sb.toString());
        }
        if (mobileWakeup > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Mobile radio AP wakeups: ");
            sb.append(mobileWakeup);
            pw.println(sb.toString());
        }
        printControllerActivityIfInteresting(pw, sb, prefix + "  ", "Modem", u.getModemControllerActivity(), which);
        if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
            pw.print(prefix);
            pw.print("    Wi-Fi network: ");
            pw.print(formatBytesLocked(wifiRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(wifiTxBytes));
            pw.print(" sent (packets ");
            pw.print(wifiRxPackets);
            pw.print(" received, ");
            pw.print(wifiTxPackets);
            pw.println(" sent)");
        }
        if (fullWifiLockOnTime != 0 || wifiScanTime != 0 || wifiScanCount != 0 || uidWifiRunningTime != 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Wifi Running: ");
            formatTimeMs(sb, uidWifiRunningTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(uidWifiRunningTime, whichBatteryRealtime));
            sb.append(")\n");
            sb.append(prefix);
            sb.append("    Full Wifi Lock: ");
            formatTimeMs(sb, fullWifiLockOnTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(fullWifiLockOnTime, whichBatteryRealtime));
            sb.append(")\n");
            sb.append(prefix);
            sb.append("    Wifi Scan: ");
            formatTimeMs(sb, wifiScanTime / 1000);
            sb.append("(");
            sb.append(formatRatioLocked(wifiScanTime, whichBatteryRealtime));
            sb.append(") ");
            sb.append(wifiScanCount);
            sb.append("x");
            pw.println(sb.toString());
        }
        if (wifiWakeup > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    WiFi AP wakeups: ");
            sb.append(wifiWakeup);
            pw.println(sb.toString());
        }
        printControllerActivityIfInteresting(pw, sb, prefix + "  ", "WiFi", u.getWifiControllerActivity(), which);
        if (btRxBytes > 0 || btTxBytes > 0) {
            pw.print(prefix);
            pw.print("    Bluetooth network: ");
            pw.print(formatBytesLocked(btRxBytes));
            pw.print(" received, ");
            pw.print(formatBytesLocked(btTxBytes));
            pw.println(" sent");
        }
        uidActivity |= printTimer(pw, sb, u.getBluetoothScanTimer(), rawRealtime, which, prefix, "Bluetooth Scan");
        if (u.hasUserActivity()) {
            boolean hasData = false;
            for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; i++) {
                final int val = u.getUserActivityCount(i, which);
                if (val != 0) {
                    if (!hasData) {
                        sb.setLength(0);
                        sb.append("    User activity: ");
                        hasData = true;
                    } else {
                        sb.append(", ");
                    }
                    sb.append(val);
                    sb.append(" ");
                    sb.append(Uid.USER_ACTIVITY_TYPES[i]);
                }
            }
            if (hasData) {
                pw.println(sb.toString());
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
        long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
        long totalDrawWakelock = 0;
        int countWakelock = 0;
        for (int iw = wakelocks.size() - 1; iw >= 0; iw--) {
            final Uid.Wakelock wl = wakelocks.valueAt(iw);
            String linePrefix = ": ";
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Wake lock ");
            sb.append(wakelocks.keyAt(iw));
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "full", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, "partial", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "window", which, linePrefix);
            linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime, "draw", which, linePrefix);
            sb.append(" realtime");
            pw.println(sb.toString());
            uidActivity = true;
            countWakelock++;
            totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, which);
            totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, which);
            totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, which);
            totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime, which);
        }
        if (countWakelock > 1) {
            if (totalFullWakelock != 0 || totalPartialWakelock != 0 || totalWindowWakelock != 0) {
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    TOTAL wake: ");
                boolean needComma = false;
                if (totalFullWakelock != 0) {
                    needComma = true;
                    formatTimeMs(sb, totalFullWakelock);
                    sb.append("full");
                }
                if (totalPartialWakelock != 0) {
                    if (needComma) {
                        sb.append(", ");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalPartialWakelock);
                    sb.append("partial");
                }
                if (totalWindowWakelock != 0) {
                    if (needComma) {
                        sb.append(", ");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalWindowWakelock);
                    sb.append("window");
                }
                if (totalDrawWakelock != 0) {
                    if (needComma) {
                        sb.append(",");
                    }
                    needComma = true;
                    formatTimeMs(sb, totalDrawWakelock);
                    sb.append("draw");
                }
                sb.append(" realtime");
                pw.println(sb.toString());
            }
        }
        final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
        for (int isy = syncs.size() - 1; isy >= 0; isy--) {
            final Timer timer = syncs.valueAt(isy);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Sync ");
            sb.append(syncs.keyAt(isy));
            sb.append(": ");
            if (totalTime != 0) {
                formatTimeMs(sb, totalTime);
                sb.append("realtime (");
                sb.append(count);
                sb.append(" times)");
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
        for (int ij = jobs.size() - 1; ij >= 0; ij--) {
            final Timer timer = jobs.valueAt(ij);
            // Convert from microseconds to milliseconds with rounding
            final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
            final int count = timer.getCountLocked(which);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Job ");
            sb.append(jobs.keyAt(ij));
            sb.append(": ");
            if (totalTime != 0) {
                formatTimeMs(sb, totalTime);
                sb.append("realtime (");
                sb.append(count);
                sb.append(" times)");
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        uidActivity |= printTimer(pw, sb, u.getFlashlightTurnedOnTimer(), rawRealtime, which, prefix, "Flashlight");
        uidActivity |= printTimer(pw, sb, u.getCameraTurnedOnTimer(), rawRealtime, which, prefix, "Camera");
        uidActivity |= printTimer(pw, sb, u.getVideoTurnedOnTimer(), rawRealtime, which, prefix, "Video");
        uidActivity |= printTimer(pw, sb, u.getAudioTurnedOnTimer(), rawRealtime, which, prefix, "Audio");
        final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
        final int NSE = sensors.size();
        for (int ise = 0; ise < NSE; ise++) {
            final Uid.Sensor se = sensors.valueAt(ise);
            final int sensorNumber = sensors.keyAt(ise);
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Sensor ");
            int handle = se.getHandle();
            if (handle == Uid.Sensor.GPS) {
                sb.append("GPS");
            } else {
                sb.append(handle);
            }
            sb.append(": ");
            final Timer timer = se.getSensorTime();
            if (timer != null) {
                // Convert from microseconds to milliseconds with rounding
                final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final int count = timer.getCountLocked(which);
                //timer.logState();
                if (totalTime != 0) {
                    formatTimeMs(sb, totalTime);
                    sb.append("realtime (");
                    sb.append(count);
                    sb.append(" times)");
                } else {
                    sb.append("(not used)");
                }
            } else {
                sb.append("(not used)");
            }
            pw.println(sb.toString());
            uidActivity = true;
        }
        uidActivity |= printTimer(pw, sb, u.getVibratorOnTimer(), rawRealtime, which, prefix, "Vibrator");
        uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which, prefix, "Foreground activities");
        long totalStateTime = 0;
        for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ips++) {
            long time = u.getProcessStateTime(ips, rawRealtime, which);
            if (time > 0) {
                totalStateTime += time;
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    ");
                sb.append(Uid.PROCESS_STATE_NAMES[ips]);
                sb.append(" for: ");
                formatTimeMs(sb, (time + 500) / 1000);
                pw.println(sb.toString());
                uidActivity = true;
            }
        }
        if (totalStateTime > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Total running: ");
            formatTimeMs(sb, (totalStateTime + 500) / 1000);
            pw.println(sb.toString());
        }
        final long userCpuTimeUs = u.getUserCpuTimeUs(which);
        final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
        final long powerCpuMaUs = u.getCpuPowerMaUs(which);
        if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) {
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    Total cpu time: u=");
            formatTimeMs(sb, userCpuTimeUs / 1000);
            sb.append("s=");
            formatTimeMs(sb, systemCpuTimeUs / 1000);
            sb.append("p=");
            printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0));
            sb.append("mAh");
            pw.println(sb.toString());
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
        for (int ipr = processStats.size() - 1; ipr >= 0; ipr--) {
            final Uid.Proc ps = processStats.valueAt(ipr);
            long userTime;
            long systemTime;
            long foregroundTime;
            int starts;
            int numExcessive;
            userTime = ps.getUserTime(which);
            systemTime = ps.getSystemTime(which);
            foregroundTime = ps.getForegroundTime(which);
            starts = ps.getStarts(which);
            final int numCrashes = ps.getNumCrashes(which);
            final int numAnrs = ps.getNumAnrs(which);
            numExcessive = which == STATS_SINCE_CHARGED ? ps.countExcessivePowers() : 0;
            if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0 || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
                sb.setLength(0);
                sb.append(prefix);
                sb.append("    Proc ");
                sb.append(processStats.keyAt(ipr));
                sb.append(":\n");
                sb.append(prefix);
                sb.append("      CPU: ");
                formatTimeMs(sb, userTime);
                sb.append("usr + ");
                formatTimeMs(sb, systemTime);
                sb.append("krn ; ");
                formatTimeMs(sb, foregroundTime);
                sb.append("fg");
                if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
                    sb.append("\n");
                    sb.append(prefix);
                    sb.append("      ");
                    boolean hasOne = false;
                    if (starts != 0) {
                        hasOne = true;
                        sb.append(starts);
                        sb.append(" starts");
                    }
                    if (numCrashes != 0) {
                        if (hasOne) {
                            sb.append(", ");
                        }
                        hasOne = true;
                        sb.append(numCrashes);
                        sb.append(" crashes");
                    }
                    if (numAnrs != 0) {
                        if (hasOne) {
                            sb.append(", ");
                        }
                        sb.append(numAnrs);
                        sb.append(" anrs");
                    }
                }
                pw.println(sb.toString());
                for (int e = 0; e < numExcessive; e++) {
                    Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
                    if (ew != null) {
                        pw.print(prefix);
                        pw.print("      * Killed for ");
                        if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
                            pw.print("wake lock");
                        } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
                            pw.print("cpu");
                        } else {
                            pw.print("unknown");
                        }
                        pw.print(" use: ");
                        TimeUtils.formatDuration(ew.usedTime, pw);
                        pw.print(" over ");
                        TimeUtils.formatDuration(ew.overTime, pw);
                        if (ew.overTime != 0) {
                            pw.print(" (");
                            pw.print((ew.usedTime * 100) / ew.overTime);
                            pw.println("%)");
                        }
                    }
                }
                uidActivity = true;
            }
        }
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            pw.print(prefix);
            pw.print("    Apk ");
            pw.print(packageStats.keyAt(ipkg));
            pw.println(":");
            boolean apkActivity = false;
            final Uid.Pkg ps = packageStats.valueAt(ipkg);
            final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                pw.print(prefix);
                pw.print("      Wakeup alarm ");
                pw.print(alarms.keyAt(iwa));
                pw.print(": ");
                pw.print(alarms.valueAt(iwa).getCountLocked(which));
                pw.println(" times");
                apkActivity = true;
            }
            final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
            for (int isvc = serviceStats.size() - 1; isvc >= 0; isvc--) {
                final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
                final long startTime = ss.getStartTime(batteryUptime, which);
                final int starts = ss.getStarts(which);
                final int launches = ss.getLaunches(which);
                if (startTime != 0 || starts != 0 || launches != 0) {
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("      Service ");
                    sb.append(serviceStats.keyAt(isvc));
                    sb.append(":\n");
                    sb.append(prefix);
                    sb.append("        Created for: ");
                    formatTimeMs(sb, startTime / 1000);
                    sb.append("uptime\n");
                    sb.append(prefix);
                    sb.append("        Starts: ");
                    sb.append(starts);
                    sb.append(", launches: ");
                    sb.append(launches);
                    pw.println(sb.toString());
                    apkActivity = true;
                }
            }
            if (!apkActivity) {
                pw.print(prefix);
                pw.println("      (nothing executed)");
            }
            uidActivity = true;
        }
        if (!uidActivity) {
            pw.print(prefix);
            pw.println("    (nothing executed)");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Comparator(java.util.Comparator) BatterySipper(com.android.internal.os.BatterySipper) BatteryStatsHelper(com.android.internal.os.BatteryStatsHelper) HashMap(java.util.HashMap) Map(java.util.Map) ArrayMap(android.util.ArrayMap)

Aggregations

BatterySipper (com.android.internal.os.BatterySipper)13 ArrayMap (android.util.ArrayMap)10 BatteryStatsHelper (com.android.internal.os.BatteryStatsHelper)10 HashMap (java.util.HashMap)10 Map (java.util.Map)10 ArrayList (java.util.ArrayList)7 Comparator (java.util.Comparator)5 Drawable (android.graphics.drawable.Drawable)1 BatteryStats (android.os.BatteryStats)1 UserHandle (android.os.UserHandle)1 SparseArray (android.util.SparseArray)1 TypedValue (android.util.TypedValue)1 DrainType (com.android.internal.os.BatterySipper.DrainType)1 PowerProfile (com.android.internal.os.PowerProfile)1