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

Commit 44e23ae2 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Add power estimation (power-profile based) to aggregated stats

Bug: 302013436
Test: atest PowerStatsTests
Change-Id: Ia7e43759d4deb1dc411bf48062f3b9a3b9d8a54a
parent a549ad5e
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -602,6 +602,17 @@ public class BatteryStatsHistory {
        initHistoryBuffer();
    }

    /**
     * Returns the monotonic clock time when the available battery history collection started.
     */
    public long getStartTime() {
        if (!mHistoryFiles.isEmpty()) {
            return mHistoryFiles.get(0).monotonicTimeMs;
        } else {
            return mHistoryBufferStartTime;
        }
    }

    /**
     * Start iterating history files and history buffer.
     *
+93 −54
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Maintains multidimensional multi-state stats.  States could be something like on-battery (0,1),
@@ -52,13 +54,55 @@ public class MultiStateStats {

        public States(String name, boolean tracked, String... labels) {
            mName = name;
            this.mTracked = tracked;
            this.mLabels = labels;
            mTracked = tracked;
            mLabels = labels;
        }

        public boolean isTracked() {
            return mTracked;
        }

        public String getName() {
            return mName;
        }

        public String[] getLabels() {
            return mLabels;
        }

        /**
         * Iterates over all combinations of tracked states and invokes <code>consumer</code>
         * for each of them.
         */
        public static void forEachTrackedStateCombination(States[] states,
                Consumer<int[]> consumer) {
            forEachTrackedStateCombination(consumer, states, new int[states.length], 0);
        }

        /**
         * Recursive function that does a depth-first traversal of the multi-dimensional
         * state space. Each time the traversal reaches the end of the <code>states</code> array,
         * <code>statesValues</code> contains a unique combination of values for all tracked states.
         * For untracked states, the corresponding values are left as 0.  The end result is
         * that the <code>consumer</code> is invoked for every unique combination of tracked state
         * values.  For example, it may be a sequence of calls like screen-on/power-on,
         * screen-on/power-off, screen-off/power-on, screen-off/power-off.
         */
        private static void forEachTrackedStateCombination(Consumer<int[]> consumer,
                States[] states, int[] statesValues, int stateIndex) {
            if (stateIndex < statesValues.length) {
                if (!states[stateIndex].mTracked) {
                    forEachTrackedStateCombination(consumer, states, statesValues, stateIndex + 1);
                    return;
                }
                for (int i = 0; i < states[stateIndex].mLabels.length; i++) {
                    statesValues[stateIndex] = i;
                    forEachTrackedStateCombination(consumer, states, statesValues, stateIndex + 1);
                }
                return;
            }
            consumer.accept(statesValues);
        }
    }

    /**
@@ -275,6 +319,13 @@ public class MultiStateStats {
        mCounter.getCounts(outValues, mFactory.getSerialState(states));
    }

    /**
     * Updates the stats values for the provided combination of states.
     */
    public void setStats(int[] states, long[] values) {
        mCounter.setValues(mFactory.getSerialState(states), values);
    }

    /**
     * Resets the counters.
     */
@@ -293,24 +344,27 @@ public class MultiStateStats {
     */
    public void writeXml(TypedXmlSerializer serializer) throws IOException {
        long[] tmpArray = new long[mCounter.getArrayLength()];
        writeXmlAllStates(serializer, new int[mFactory.mStates.length], 0, tmpArray);
    }

    private void writeXmlAllStates(TypedXmlSerializer serializer, int[] states, int stateIndex,
            long[] values) throws IOException {
        if (stateIndex < states.length) {
            if (!mFactory.mStates[stateIndex].mTracked) {
                writeXmlAllStates(serializer, states, stateIndex + 1, values);
                return;
        try {
            States.forEachTrackedStateCombination(mFactory.mStates,
                    states -> {
                        try {
                            writeXmlForStates(serializer, states, tmpArray);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
        } catch (RuntimeException e) {
            if (e.getCause() instanceof IOException) {
                throw (IOException) e.getCause();
            } else {
                throw e;
            }

            for (int i = 0; i < mFactory.mStates[stateIndex].mLabels.length; i++) {
                states[stateIndex] = i;
                writeXmlAllStates(serializer, states, stateIndex + 1, values);
        }
            return;
    }

    private void writeXmlForStates(TypedXmlSerializer serializer, int[] states, long[] values)
            throws IOException {
        mCounter.getCounts(values, mFactory.getSerialState(states));
        boolean nonZero = false;
        for (long value : values) {
@@ -391,25 +445,9 @@ public class MultiStateStats {
    /**
     * Prints the accumulated stats, one line of every combination of states that has data.
     */
    public void dump(PrintWriter pw) {
        long[] tmpArray = new long[mCounter.getArrayLength()];
        dumpAllStates(pw, new int[mFactory.mStates.length], 0, tmpArray);
    }

    private void dumpAllStates(PrintWriter pw, int[] states, int stateIndex, long[] values) {
        if (stateIndex < states.length) {
            if (!mFactory.mStates[stateIndex].mTracked) {
                dumpAllStates(pw, states, stateIndex + 1, values);
                return;
            }

            for (int i = 0; i < mFactory.mStates[stateIndex].mLabels.length; i++) {
                states[stateIndex] = i;
                dumpAllStates(pw, states, stateIndex + 1, values);
            }
            return;
        }

    public void dump(PrintWriter pw, Function<long[], String> statsFormatter) {
        long[] values = new long[mCounter.getArrayLength()];
        States.forEachTrackedStateCombination(mFactory.mStates, states -> {
            mCounter.getCounts(values, mFactory.getSerialState(states));
            boolean nonZero = false;
            for (long value : values) {
@@ -432,7 +470,8 @@ public class MultiStateStats {
                }
            }
            sb.append(" ");
        sb.append(Arrays.toString(values));
            sb.append(statsFormatter.apply(values));
            pw.println(sb);
        });
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -55,12 +55,12 @@ public final class PowerStats {
    private static final int STATS_ARRAY_LENGTH_SHIFT =
            Integer.numberOfTrailingZeros(STATS_ARRAY_LENGTH_MASK);
    public static final int MAX_STATS_ARRAY_LENGTH =
            2 ^ Integer.bitCount(STATS_ARRAY_LENGTH_MASK) - 1;
            (1 << Integer.bitCount(STATS_ARRAY_LENGTH_MASK)) - 1;
    private static final int UID_STATS_ARRAY_LENGTH_MASK = 0x00FF0000;
    private static final int UID_STATS_ARRAY_LENGTH_SHIFT =
            Integer.numberOfTrailingZeros(UID_STATS_ARRAY_LENGTH_MASK);
    public static final int MAX_UID_STATS_ARRAY_LENGTH =
            (2 ^ Integer.bitCount(UID_STATS_ARRAY_LENGTH_MASK)) - 1;
            (1 << Integer.bitCount(UID_STATS_ARRAY_LENGTH_MASK)) - 1;

    /**
     * Descriptor of the stats collected for a given power component (e.g. CPU, WiFi etc).
+4 −1
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ import com.android.server.power.stats.AggregatedPowerStatsConfig;
import com.android.server.power.stats.BatteryExternalStatsWorker;
import com.android.server.power.stats.BatteryStatsImpl;
import com.android.server.power.stats.BatteryUsageStatsProvider;
import com.android.server.power.stats.CpuAggregatedPowerStatsProcessor;
import com.android.server.power.stats.PowerStatsAggregator;
import com.android.server.power.stats.PowerStatsScheduler;
import com.android.server.power.stats.PowerStatsStore;
@@ -440,7 +441,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                .trackUidStates(
                        AggregatedPowerStatsConfig.STATE_POWER,
                        AggregatedPowerStatsConfig.STATE_SCREEN,
                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
                .setProcessor(
                        new CpuAggregatedPowerStatsProcessor(mPowerProfile, mCpuScalingPolicies));
        return config;
    }

+1 −12
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.power.stats;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
import android.os.BatteryConsumer;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.IndentingPrintWriter;
@@ -66,17 +65,7 @@ class AggregatedPowerStats {
                aggregatedPowerStatsConfig.getPowerComponentsAggregatedStatsConfigs();
        mPowerComponentStats = new PowerComponentAggregatedPowerStats[configs.size()];
        for (int i = 0; i < configs.size(); i++) {
            mPowerComponentStats[i] = createPowerComponentAggregatedPowerStats(configs.get(i));
        }
    }

    private PowerComponentAggregatedPowerStats createPowerComponentAggregatedPowerStats(
            AggregatedPowerStatsConfig.PowerComponent config) {
        switch (config.getPowerComponentId()) {
            case BatteryConsumer.POWER_COMPONENT_CPU:
                return new CpuAggregatedPowerStats(config);
            default:
                return new PowerComponentAggregatedPowerStats(config);
            mPowerComponentStats[i] = new PowerComponentAggregatedPowerStats(configs.get(i));
        }
    }

Loading