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

Commit 4eda903a authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Accumulate battery usage stats incrementally

Process just the yet-unprocessed span of battery history
on each accumulation pass

Bug: 345022340
Test: atest PowerStatsTests; atest PowerStatsTestsRavenwood
Flag: com.android.server.power.optimization.accumulate_battery_usage_stats
Change-Id: I2829c830acac26705176258b0e02e1b5e5df3e4a
parent 9f5fe214
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1031,7 +1031,10 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
            return this;
        }

        private long getStatsDuration() {
        /**
         * Returns the duration of the battery session reflected by these stats.
         */
        public long getStatsDuration() {
            if (mStatsDurationMs != -1) {
                return mStatsDurationMs;
            } else {
+53 −17
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.util.IntArray;

import com.android.internal.os.MonotonicClock;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@@ -85,8 +87,11 @@ public final class BatteryUsageStatsQuery implements Parcelable {
    @NonNull
    private final int[] mUserIds;
    private final long mMaxStatsAgeMs;
    private final long mFromTimestamp;
    private final long mToTimestamp;

    private final long mAggregatedFromTimestamp;
    private final long mAggregatedToTimestamp;
    private long mMonotonicStartTime;
    private long mMonotonicEndTime;
    private final double mMinConsumedPowerThreshold;
    private final @BatteryConsumer.PowerComponentId int[] mPowerComponents;

@@ -96,8 +101,10 @@ public final class BatteryUsageStatsQuery implements Parcelable {
                : new int[]{UserHandle.USER_ALL};
        mMaxStatsAgeMs = builder.mMaxStatsAgeMs;
        mMinConsumedPowerThreshold = builder.mMinConsumedPowerThreshold;
        mFromTimestamp = builder.mFromTimestamp;
        mToTimestamp = builder.mToTimestamp;
        mAggregatedFromTimestamp = builder.mAggregateFromTimestamp;
        mAggregatedToTimestamp = builder.mAggregateToTimestamp;
        mMonotonicStartTime = builder.mMonotonicStartTime;
        mMonotonicEndTime = builder.mMonotonicEndTime;
        mPowerComponents = builder.mPowerComponents;
    }

@@ -162,12 +169,28 @@ public final class BatteryUsageStatsQuery implements Parcelable {
        return mMinConsumedPowerThreshold;
    }

    /**
     * Returns the exclusive lower bound of the battery history that should be included in
     * the aggregated battery usage stats.
     */
    public long getMonotonicStartTime() {
        return mMonotonicStartTime;
    }

    /**
     * Returns the inclusive upper bound of the battery history that should be included in
     * the aggregated battery usage stats.
     */
    public long getMonotonicEndTime() {
        return mMonotonicEndTime;
    }

    /**
     * Returns the exclusive lower bound of the stored snapshot timestamps that should be included
     * in the aggregation.  Ignored if {@link #getToTimestamp()} is zero.
     * in the aggregation.  Ignored if {@link #getAggregatedToTimestamp()} is zero.
     */
    public long getFromTimestamp() {
        return mFromTimestamp;
    public long getAggregatedFromTimestamp() {
        return mAggregatedFromTimestamp;
    }

    /**
@@ -175,8 +198,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
     * be included in the aggregation.  The default is to include only the current stats
     * accumulated since the latest battery reset.
     */
    public long getToTimestamp() {
        return mToTimestamp;
    public long getAggregatedToTimestamp() {
        return mAggregatedToTimestamp;
    }

    private BatteryUsageStatsQuery(Parcel in) {
@@ -185,8 +208,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
        in.readIntArray(mUserIds);
        mMaxStatsAgeMs = in.readLong();
        mMinConsumedPowerThreshold = in.readDouble();
        mFromTimestamp = in.readLong();
        mToTimestamp = in.readLong();
        mAggregatedFromTimestamp = in.readLong();
        mAggregatedToTimestamp = in.readLong();
        mPowerComponents = in.createIntArray();
    }

@@ -197,8 +220,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
        dest.writeIntArray(mUserIds);
        dest.writeLong(mMaxStatsAgeMs);
        dest.writeDouble(mMinConsumedPowerThreshold);
        dest.writeLong(mFromTimestamp);
        dest.writeLong(mToTimestamp);
        dest.writeLong(mAggregatedFromTimestamp);
        dest.writeLong(mAggregatedToTimestamp);
        dest.writeIntArray(mPowerComponents);
    }

@@ -228,8 +251,10 @@ public final class BatteryUsageStatsQuery implements Parcelable {
        private int mFlags;
        private IntArray mUserIds;
        private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS;
        private long mFromTimestamp;
        private long mToTimestamp;
        private long mMonotonicStartTime = MonotonicClock.UNDEFINED;
        private long mMonotonicEndTime = MonotonicClock.UNDEFINED;
        private long mAggregateFromTimestamp;
        private long mAggregateToTimestamp;
        private double mMinConsumedPowerThreshold = 0;
        private @BatteryConsumer.PowerComponentId int[] mPowerComponents;

@@ -240,6 +265,17 @@ public final class BatteryUsageStatsQuery implements Parcelable {
            return new BatteryUsageStatsQuery(this);
        }

        /**
         * Specifies the time range for the requested stats, in terms of MonotonicClock
         * @param monotonicStartTime Inclusive starting monotonic timestamp
         * @param monotonicEndTime Exclusive ending timestamp. Can be MonotonicClock.UNDEFINED
         */
        public Builder monotonicTimeRange(long monotonicStartTime, long monotonicEndTime) {
            mMonotonicStartTime = monotonicStartTime;
            mMonotonicEndTime = monotonicEndTime;
            return this;
        }

        /**
         * Add a user whose battery stats should be included in the battery usage stats.
         * {@link UserHandle#USER_ALL} will be used by default if no users are added explicitly.
@@ -345,8 +381,8 @@ public final class BatteryUsageStatsQuery implements Parcelable {
         */
        // TODO(b/298459065): switch to monotonic clock
        public Builder aggregateSnapshots(long fromTimestamp, long toTimestamp) {
            mFromTimestamp = fromTimestamp;
            mToTimestamp = toTimestamp;
            mAggregateFromTimestamp = fromTimestamp;
            mAggregateToTimestamp = toTimestamp;
            return this;
        }

+5 −3
Original line number Diff line number Diff line
@@ -109,10 +109,12 @@ public final class UidBatteryConsumer extends BatteryConsumer {
     * Returns the amount of time in milliseconds this UID spent in the specified process state.
     */
    public long getTimeInProcessStateMs(@ProcessState int state) {
        if (state != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
            Key key = getKey(POWER_COMPONENT_BASE, state);
            if (key != null) {
                return getUsageDurationMillis(key);
            }
        }
        return 0;
    }

+21 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public class BatteryStatsHistory {
    private static final String TAG = "BatteryStatsHistory";

    // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
    private static final int VERSION = 210;
    private static final int VERSION = 211;

    private static final String HISTORY_DIR = "battery-history";
    private static final String FILE_SUFFIX = ".bh";
@@ -210,6 +210,8 @@ public class BatteryStatsHistory {
    private final MonotonicClock mMonotonicClock;
    // Monotonic time when we started writing to the history buffer
    private long mHistoryBufferStartTime;
    // Monotonically increasing size of written history
    private long mMonotonicHistorySize;
    private final ArraySet<PowerStats.Descriptor> mWrittenPowerStatsDescriptors = new ArraySet<>();
    private byte mLastHistoryStepLevel = 0;
    private boolean mMutable = true;
@@ -909,6 +911,8 @@ public class BatteryStatsHistory {
                }
                // skip monotonic time field.
                p.readLong();
                // skip monotonic size field
                p.readLong();

                final int bufSize = p.readInt();
                final int curPos = p.dataPosition();
@@ -964,6 +968,8 @@ public class BatteryStatsHistory {
        }
        // skip monotonic time field.
        out.readLong();
        // skip monotonic size field
        out.readLong();
        return true;
    }

@@ -987,6 +993,7 @@ public class BatteryStatsHistory {
        p.setDataPosition(0);
        p.readInt();        // Skip the version field
        long monotonicTime = p.readLong();
        p.readLong();       // Skip monotonic size field
        p.setDataPosition(pos);
        return monotonicTime;
    }
@@ -1819,6 +1826,7 @@ public class BatteryStatsHistory {
            // as long as no bit has changed both between now and the last entry, as
            // well as the last entry and the one before it (so we capture any toggles).
            if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
            mMonotonicHistorySize -= (mHistoryBuffer.dataSize() - mHistoryBufferLastPos);
            mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
            mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
            mHistoryBufferLastPos = -1;
@@ -1934,6 +1942,7 @@ public class BatteryStatsHistory {
        }
        mHistoryLastWritten.tagsFirstOccurrence = hasTags;
        writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
        mMonotonicHistorySize += (mHistoryBuffer.dataSize() - mHistoryBufferLastPos);
        cur.wakelockTag = null;
        cur.wakeReasonTag = null;
        cur.eventCode = HistoryItem.EVENT_NONE;
@@ -2344,6 +2353,8 @@ public class BatteryStatsHistory {
            }

            mHistoryBufferStartTime = in.readLong();
            mMonotonicHistorySize = in.readLong();

            mHistoryBuffer.setDataSize(0);
            mHistoryBuffer.setDataPosition(0);

@@ -2370,6 +2381,7 @@ public class BatteryStatsHistory {
    private void writeHistoryBuffer(Parcel out) {
        out.writeInt(BatteryStatsHistory.VERSION);
        out.writeLong(mHistoryBufferStartTime);
        out.writeLong(mMonotonicHistorySize);
        out.writeInt(mHistoryBuffer.dataSize());
        if (DEBUG) {
            Slog.i(TAG, "***************** WRITING HISTORY: "
@@ -2456,6 +2468,14 @@ public class BatteryStatsHistory {
        }
    }

    /**
     * Returns the monotonically increasing size of written history, including the buffers
     * that have already been discarded.
     */
    public long getMonotonicHistorySize() {
        return mMonotonicHistorySize;
    }

    /**
     * Prints battery stats history for debugging.
     */
+6 −1
Original line number Diff line number Diff line
@@ -45,7 +45,12 @@
    <integer name="config_powerStatsAggregationPeriod">14400000</integer>

    <!-- PowerStats aggregation span duration in milliseconds. This is the length of battery
    history time for every aggregated power stats span that is stored stored in PowerStatsStore.
    history time for every aggregated power stats span that is stored in PowerStatsStore.
    It should not be larger than config_powerStatsAggregationPeriod (but it can be the same) -->
    <integer name="config_aggregatedPowerStatsSpanDuration">3600000</integer>

    <!-- BatteryUsageStats accumulation period as determined by the size of accumulated
    battery history, in bytes. -->
    <integer name="config_accumulatedBatteryUsageStatsSpanSize">32768</integer>

</resources>
Loading