Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2dd7e5e3 authored by James Carr's avatar James Carr
Browse files

Calculate and account for memory power use

Use PowerProfile to calculate mAh (MemoryPowerCalculator), and
involve this calculation in the overall accounting of battery
for when the phone is unplugged from a charger.

Note: Depends on ag/1196281

Change-Id: Id02bef19c9b250c614df0a6c88711b486faaef46
parent dfccb8b3
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.content.pm.ApplicationInfo;
import android.telephony.SignalStrength;
import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.LongSparseArray;
import android.util.MutableBoolean;
import android.util.Pair;
import android.util.Printer;
@@ -2450,6 +2451,8 @@ public abstract class BatteryStats implements Parcelable {

    public abstract Map<String, ? extends Timer> getKernelWakelockStats();

    public abstract LongSparseArray<? extends Timer> getKernelMemoryStats();

    public abstract void writeToParcelWithoutUids(Parcel out, int flags);

    private final static void formatTimeRaw(StringBuilder out, long seconds) {
@@ -4116,6 +4119,17 @@ public abstract class BatteryStats implements Parcelable {
            }
        }

        final LongSparseArray<? extends Timer> mMemoryStats = getKernelMemoryStats();
        pw.println("Memory Stats");
        for (int i = 0; i < mMemoryStats.size(); i++) {
            sb.setLength(0);
            sb.append("Bandwidth ");
            sb.append(mMemoryStats.keyAt(i));
            sb.append(" Time ");
            sb.append(mMemoryStats.valueAt(i).getTotalTimeLocked(rawRealtime, which));
            pw.println(sb.toString());
        }

        for (int iu=0; iu<NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
+2 −1
Original line number Diff line number Diff line
@@ -88,7 +88,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
        USER,
        UNACCOUNTED,
        OVERCOUNTED,
        CAMERA
        CAMERA,
        MEMORY
    }

    public BatterySipper(DrainType drainType, Uid uid, double value) {
+17 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ public final class BatteryStatsHelper {
    PowerCalculator mSensorPowerCalculator;
    PowerCalculator mCameraPowerCalculator;
    PowerCalculator mFlashlightPowerCalculator;
    PowerCalculator mMemoryPowerCalculator;

    boolean mHasWifiPowerReporting = false;
    boolean mHasBluetoothPowerReporting = false;
@@ -342,6 +343,11 @@ public final class BatteryStatsHelper {
        }
        mCpuPowerCalculator.reset();

        if (mMemoryPowerCalculator == null) {
            mMemoryPowerCalculator = new MemoryPowerCalculator(mPowerProfile);
        }
        mMemoryPowerCalculator.reset();

        if (mWakelockPowerCalculator == null) {
            mWakelockPowerCalculator = new WakelockPowerCalculator(mPowerProfile);
        }
@@ -672,12 +678,23 @@ public final class BatteryStatsHelper {
        }
    }

    private void addMemoryUsage() {
        BatterySipper memory = new BatterySipper(DrainType.MEMORY, null, 0);
        mMemoryPowerCalculator.calculateRemaining(memory, mStats, mRawRealtimeUs, mRawUptimeUs,
                mStatsType);
        memory.sumPower();
        if (memory.totalPowerMah > 0) {
            mUsageList.add(memory);
        }
    }

    private void processMiscUsage() {
        addUserUsage();
        addPhoneUsage();
        addScreenUsage();
        addWiFiUsage();
        addBluetoothUsage();
        addMemoryUsage();
        addIdleUsage(); // Not including cellular idle power
        // Don't compute radio usage if it's a wifi-only device
        if (!mWifiOnly) {
+54 −0
Original line number Diff line number Diff line
package com.android.internal.os;

import android.os.BatteryStats;
import android.util.Log;
import android.util.LongSparseArray;

public class MemoryPowerCalculator extends PowerCalculator {

    public static final String TAG = "MemoryPowerCalculator";
    private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
    private final double[] powerAverages;

    public MemoryPowerCalculator(PowerProfile profile) {
        int numBuckets = profile.getNumElements(PowerProfile.POWER_MEMORY);
        powerAverages = new double[numBuckets];
        for (int i = 0; i < numBuckets; i++) {
            powerAverages[i] = profile.getAveragePower(PowerProfile.POWER_MEMORY, i);
            if (powerAverages[i] == 0 && DEBUG) {
                Log.d(TAG, "Problem with PowerProfile. Received 0 value in MemoryPowerCalculator");
            }
        }
    }

    @Override
    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
            long rawUptimeUs, int statsType) {}

    @Override
    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
            long rawUptimeUs, int statsType) {
        double totalMah = 0;
        long totalTimeMs = 0;
        LongSparseArray<? extends BatteryStats.Timer> timers = stats.getKernelMemoryStats();
        for (int i = 0; i < timers.size() && i < powerAverages.length; i++) {
            double mAatRail = powerAverages[(int) timers.keyAt(i)];
            long timeMs = timers.valueAt(i).getTotalTimeLocked(rawRealtimeUs, statsType);
            double mAm = (mAatRail * timeMs) / (1000*60);
            if(DEBUG) {
                Log.d(TAG, "Calculating mAh for bucket " + timers.keyAt(i) + " while unplugged");
                Log.d(TAG, "Converted power profile number from "
                        + powerAverages[(int) timers.keyAt(i)] + " into " + mAatRail);
                Log.d(TAG, "Calculated mAm " + mAm);
            }
            totalMah += mAm/60;
            totalTimeMs += timeMs;
        }
        app.usagePowerMah = totalMah;
        app.usageTimeMs = totalTimeMs;
        if (DEBUG) {
            Log.d(TAG, String.format("Calculated total mAh for memory %f while unplugged %d ",
                    totalMah, totalTimeMs));
        }
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -170,6 +170,11 @@ public class PowerProfile {
     */
    public static final String POWER_FLASHLIGHT = "camera.flashlight";

    /**
     * Power consumption when DDR is being used.
     */
    public static final String POWER_MEMORY = "memory.bandwidths";

    /**
     * Average power consumption when the camera is on over all standard use cases.
     *
@@ -364,6 +369,24 @@ public class PowerProfile {
        return 0;
    }

    /**
     * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
     * default value if the subsystem has no recorded value.
     * @return the number of memory bandwidth buckets.
     */
    public int getNumElements(String key) {
        if (sPowerMap.containsKey(key)) {
            Object data = sPowerMap.get(key);
            if (data instanceof Double[]) {
                final Double[] values = (Double[]) data;
                return values.length;
            } else {
                return 1;
            }
        }
        return 0;
    }

    /**
     * Returns the average current in mA consumed by the subsystem, or the given
     * default value if the subsystem has no recorded value.
Loading