Search in sources :

Example 81 with ArrayMap

use of android.util.ArrayMap in project platform_frameworks_base by android.

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 82 with ArrayMap

use of android.util.ArrayMap in project platform_frameworks_base by android.

the class NetworkSecurityConfig method getTrustAnchors.

public Set<TrustAnchor> getTrustAnchors() {
    synchronized (mAnchorsLock) {
        if (mAnchors != null) {
            return mAnchors;
        }
        // Merge trust anchors based on the X509Certificate.
        // If we see the same certificate in two TrustAnchors, one with overridesPins and one
        // without, the one with overridesPins wins.
        // Because mCertificatesEntryRefs is sorted with all overridesPins anchors coming first
        // this can be simplified to just using the first occurrence of a certificate.
        Map<X509Certificate, TrustAnchor> anchorMap = new ArrayMap<>();
        for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
            Set<TrustAnchor> anchors = ref.getTrustAnchors();
            for (TrustAnchor anchor : anchors) {
                X509Certificate cert = anchor.certificate;
                if (!anchorMap.containsKey(cert)) {
                    anchorMap.put(cert, anchor);
                }
            }
        }
        ArraySet<TrustAnchor> anchors = new ArraySet<TrustAnchor>(anchorMap.size());
        anchors.addAll(anchorMap.values());
        mAnchors = anchors;
        return mAnchors;
    }
}
Also used : ArraySet(android.util.ArraySet) ArrayMap(android.util.ArrayMap) X509Certificate(java.security.cert.X509Certificate)

Example 83 with ArrayMap

use of android.util.ArrayMap in project freeline by alibaba.

the class MonkeyPatcher method monkeyPatchExistingResources.

public static void monkeyPatchExistingResources(Context context, String externalResourceFile, Collection<Activity> activities) {
    if (externalResourceFile == null) {
        return;
    }
    /*
        (Note: the resource directory is *also* inserted into the loadedApk in
        monkeyPatchApplication)
        The code seems to perform this:
        File externalResourceFile = <path to resources.ap_ or extracted directory>
        AssetManager newAssetManager = new AssetManager();
        newAssetManager.addAssetPath(externalResourceFile)
        // Kitkat needs this method call, Lollipop doesn't. However, it doesn't seem to cause any harm
        // in L, so we do it unconditionally.
        newAssetManager.ensureStringBlocks();
        // Find the singleton instance of ResourcesManager
        ResourcesManager resourcesManager = ResourcesManager.getInstance();
        // Iterate over all known Resources objects
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            for (WeakReference<Resources> wr : resourcesManager.mActiveResources.values()) {
                Resources resources = wr.get();
                // Set the AssetManager of the Resources instance to our brand new one
                resources.mAssets = newAssetManager;
                resources.updateConfiguration(resources.getConfiguration(), resources.getDisplayMetrics());
            }
        }
        // Also, for each context, call getTheme() to get the current theme; null out its
        // mTheme field, then invoke initializeTheme() to force it to be recreated (with the
        // new asset manager!)
        */
    try {
        // Create a new AssetManager instance and point it to the resources installed under
        // /sdcard
        AssetManager newAssetManager = AssetManager.class.getConstructor().newInstance();
        Method mAddAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
        mAddAssetPath.setAccessible(true);
        if (((Integer) mAddAssetPath.invoke(newAssetManager, externalResourceFile)) == 0) {
            throw new IllegalStateException("Could not create new AssetManager");
        }
        // Kitkat needs this method call, Lollipop doesn't. However, it doesn't seem to cause any harm
        // in L, so we do it unconditionally.
        Method mEnsureStringBlocks = AssetManager.class.getDeclaredMethod("ensureStringBlocks");
        mEnsureStringBlocks.setAccessible(true);
        mEnsureStringBlocks.invoke(newAssetManager);
        if (activities != null) {
            for (Activity activity : activities) {
                Resources resources = activity.getResources();
                try {
                    Field mAssets = Resources.class.getDeclaredField("mAssets");
                    mAssets.setAccessible(true);
                    mAssets.set(resources, newAssetManager);
                } catch (Throwable ignore) {
                    Field mResourcesImpl = Resources.class.getDeclaredField("mResourcesImpl");
                    mResourcesImpl.setAccessible(true);
                    Object resourceImpl = mResourcesImpl.get(resources);
                    Field implAssets = resourceImpl.getClass().getDeclaredField("mAssets");
                    implAssets.setAccessible(true);
                    implAssets.set(resourceImpl, newAssetManager);
                }
                Resources.Theme theme = activity.getTheme();
                try {
                    try {
                        Field ma = Resources.Theme.class.getDeclaredField("mAssets");
                        ma.setAccessible(true);
                        ma.set(theme, newAssetManager);
                    } catch (NoSuchFieldException ignore) {
                        Field themeField = Resources.Theme.class.getDeclaredField("mThemeImpl");
                        themeField.setAccessible(true);
                        Object impl = themeField.get(theme);
                        Field ma = impl.getClass().getDeclaredField("mAssets");
                        ma.setAccessible(true);
                        ma.set(impl, newAssetManager);
                    }
                    Field mt = ContextThemeWrapper.class.getDeclaredField("mTheme");
                    mt.setAccessible(true);
                    mt.set(activity, null);
                    Method mtm = ContextThemeWrapper.class.getDeclaredMethod("initializeTheme");
                    mtm.setAccessible(true);
                    mtm.invoke(activity);
                    if (SDK_INT < N) {
                        Method mCreateTheme = AssetManager.class.getDeclaredMethod("createTheme");
                        mCreateTheme.setAccessible(true);
                        Object internalTheme = mCreateTheme.invoke(newAssetManager);
                        Field mTheme = Resources.Theme.class.getDeclaredField("mTheme");
                        mTheme.setAccessible(true);
                        mTheme.set(theme, internalTheme);
                    }
                } catch (Throwable e) {
                    Log.e(LOG_TAG, "Failed to update existing theme for activity " + activity, e);
                }
                pruneResourceCaches(resources);
            }
        }
        // Iterate over all known Resources objects
        Collection<WeakReference<Resources>> references;
        if (SDK_INT >= KITKAT) {
            // Find the singleton instance of ResourcesManager
            Class<?> resourcesManagerClass = Class.forName("android.app.ResourcesManager");
            Method mGetInstance = resourcesManagerClass.getDeclaredMethod("getInstance");
            mGetInstance.setAccessible(true);
            Object resourcesManager = mGetInstance.invoke(null);
            try {
                Field fMActiveResources = resourcesManagerClass.getDeclaredField("mActiveResources");
                fMActiveResources.setAccessible(true);
                @SuppressWarnings("unchecked") ArrayMap<?, WeakReference<Resources>> arrayMap = (ArrayMap<?, WeakReference<Resources>>) fMActiveResources.get(resourcesManager);
                references = arrayMap.values();
            } catch (NoSuchFieldException ignore) {
                Field mResourceReferences = resourcesManagerClass.getDeclaredField("mResourceReferences");
                mResourceReferences.setAccessible(true);
                //noinspection unchecked
                references = (Collection<WeakReference<Resources>>) mResourceReferences.get(resourcesManager);
            }
        } else {
            Class<?> activityThread = Class.forName("android.app.ActivityThread");
            Field fMActiveResources = activityThread.getDeclaredField("mActiveResources");
            fMActiveResources.setAccessible(true);
            Object thread = getActivityThread(context, activityThread);
            @SuppressWarnings("unchecked") HashMap<?, WeakReference<Resources>> map = (HashMap<?, WeakReference<Resources>>) fMActiveResources.get(thread);
            references = map.values();
        }
        for (WeakReference<Resources> wr : references) {
            Resources resources = wr.get();
            if (resources != null) {
                // Set the AssetManager of the Resources instance to our brand new one
                try {
                    Field mAssets = Resources.class.getDeclaredField("mAssets");
                    mAssets.setAccessible(true);
                    mAssets.set(resources, newAssetManager);
                } catch (Throwable ignore) {
                    Field mResourcesImpl = Resources.class.getDeclaredField("mResourcesImpl");
                    mResourcesImpl.setAccessible(true);
                    Object resourceImpl = mResourcesImpl.get(resources);
                    Field implAssets = resourceImpl.getClass().getDeclaredField("mAssets");
                    implAssets.setAccessible(true);
                    implAssets.set(resourceImpl, newAssetManager);
                }
                resources.updateConfiguration(resources.getConfiguration(), resources.getDisplayMetrics());
            }
        }
    } catch (Throwable e) {
        throw new IllegalStateException(e);
    }
}
Also used : AssetManager(android.content.res.AssetManager) HashMap(java.util.HashMap) Activity(android.app.Activity) ArrayMap(android.util.ArrayMap) Method(java.lang.reflect.Method) Field(java.lang.reflect.Field) WeakReference(java.lang.ref.WeakReference) Collection(java.util.Collection) Resources(android.content.res.Resources)

Example 84 with ArrayMap

use of android.util.ArrayMap in project platform_frameworks_base by android.

the class ResourcesManager method appendLibAssetForMainAssetPath.

/**
     * Appends the library asset path to any ResourcesImpl object that contains the main
     * assetPath.
     * @param assetPath The main asset path for which to add the library asset path.
     * @param libAsset The library asset path to add.
     */
public void appendLibAssetForMainAssetPath(String assetPath, String libAsset) {
    synchronized (this) {
        // Record which ResourcesImpl need updating
        // (and what ResourcesKey they should update to).
        final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
        final int implCount = mResourceImpls.size();
        for (int i = 0; i < implCount; i++) {
            final ResourcesKey key = mResourceImpls.keyAt(i);
            final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
            final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
            if (impl != null && key.mResDir.equals(assetPath)) {
                if (!ArrayUtils.contains(key.mLibDirs, libAsset)) {
                    final int newLibAssetCount = 1 + (key.mLibDirs != null ? key.mLibDirs.length : 0);
                    final String[] newLibAssets = new String[newLibAssetCount];
                    if (key.mLibDirs != null) {
                        System.arraycopy(key.mLibDirs, 0, newLibAssets, 0, key.mLibDirs.length);
                    }
                    newLibAssets[newLibAssetCount - 1] = libAsset;
                    updatedResourceKeys.put(impl, new ResourcesKey(key.mResDir, key.mSplitResDirs, key.mOverlayDirs, newLibAssets, key.mDisplayId, key.mOverrideConfiguration, key.mCompatInfo));
                }
            }
        }
        // Bail early if there is no work to do.
        if (updatedResourceKeys.isEmpty()) {
            return;
        }
        // Update any references to ResourcesImpl that require reloading.
        final int resourcesCount = mResourceReferences.size();
        for (int i = 0; i < resourcesCount; i++) {
            final Resources r = mResourceReferences.get(i).get();
            if (r != null) {
                final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
                if (key != null) {
                    final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
                    if (impl == null) {
                        throw new Resources.NotFoundException("failed to load " + libAsset);
                    }
                    r.setImpl(impl);
                }
            }
        }
        // Update any references to ResourcesImpl that require reloading for each Activity.
        for (ActivityResources activityResources : mActivityResourceReferences.values()) {
            final int resCount = activityResources.activityResources.size();
            for (int i = 0; i < resCount; i++) {
                final Resources r = activityResources.activityResources.get(i).get();
                if (r != null) {
                    final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
                    if (key != null) {
                        final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
                        if (impl == null) {
                            throw new Resources.NotFoundException("failed to load " + libAsset);
                        }
                        r.setImpl(impl);
                    }
                }
            }
        }
    }
}
Also used : ResourcesKey(android.content.res.ResourcesKey) ArrayMap(android.util.ArrayMap) Resources(android.content.res.Resources) ResourcesImpl(android.content.res.ResourcesImpl)

Example 85 with ArrayMap

use of android.util.ArrayMap in project android_frameworks_base by crdroidandroid.

the class FullBackupTest method setUp.

@Override
public void setUp() throws Exception {
    mFactory = XmlPullParserFactory.newInstance();
    mXpp = mFactory.newPullParser();
    mContext = getContext();
    includeMap = new ArrayMap();
    excludesSet = new ArraySet();
}
Also used : ArraySet(android.util.ArraySet) ArrayMap(android.util.ArrayMap)

Aggregations

ArrayMap (android.util.ArrayMap)365 ArraySet (android.util.ArraySet)77 ArrayList (java.util.ArrayList)75 PublicKey (java.security.PublicKey)49 HashMap (java.util.HashMap)32 Preference (android.support.v7.preference.Preference)30 IOException (java.io.IOException)30 Map (java.util.Map)29 HashSet (java.util.HashSet)28 Intent (android.content.Intent)24 Test (org.junit.Test)24 ComponentName (android.content.ComponentName)22 RemoteException (android.os.RemoteException)22 Field (java.lang.reflect.Field)21 Activity (android.app.Activity)20 SparseArray (android.util.SparseArray)18 List (java.util.List)18 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)18 Point (android.graphics.Point)17 Method (java.lang.reflect.Method)17