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

Commit 5f133383 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Fix CPU attribution when power stats collection is enabled

The BatteryUsageStatsTests collects battery usage stats over a short
period of time immediately after a reset, not allowing
PowerStatsCollector to gather enough data organically.
We need to force data collection before generating battery usage stats.

Bug: 313830933
Test: atest CtsStatsdAtomHostTestCases:android.cts.statsdatom.batterystats.BatteryUsageStatsTests
Test: atest PowerStatsTests

Change-Id: I55e3f76975ea86315dd6d166ace96a0db64b271e
parent 396d3091
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -886,10 +886,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
        }

        synchronized (mStats) {
        return mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, queries);
    }
    }

    /** Register callbacks for statsd pulled atoms. */
    private void registerStatsCallbacks() {
@@ -2730,6 +2728,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
        BatteryUsageStatsQuery query = builder.build();
        synchronized (mStats) {
            mStats.prepareForDumpLocked();
        }
        BatteryUsageStats batteryUsageStats =
                mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, query);
        if (proto) {
@@ -2738,7 +2737,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            batteryUsageStats.dump(pw, "");
        }
    }
    }

    private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
        i++;
+16 −2
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.os.BatteryUsageStatsQuery;
import android.os.Binder;
import android.os.BluetoothBatteryStats;
import android.os.Build;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.IBatteryPropertiesRegistrar;
import android.os.Looper;
@@ -137,7 +138,6 @@ import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.server.power.optimization.Flags;
import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
import libcore.util.EmptyArray;
@@ -10543,7 +10543,7 @@ public class BatteryStatsImpl extends BatteryStats {
                final int batteryConsumerProcessState =
                        mapUidProcessStateToBatteryConsumerProcessState(uidRunningState);
                if (mBsi.mSystemReady && Flags.streamlinedBatteryStats()) {
                if (mBsi.mSystemReady && mBsi.mPowerStatsCollectorEnabled) {
                    mBsi.mHistory.recordProcessStateChange(elapsedRealtimeMs, uptimeMs, mUid,
                            batteryConsumerProcessState);
                }
@@ -11712,6 +11712,10 @@ public class BatteryStatsImpl extends BatteryStats {
        // Store the empty state to disk to ensure consistency
        writeSyncLocked();
        if (mPowerStatsCollectorEnabled) {
            schedulePowerStatsSampleCollection();
        }
        // Flush external data, gathering snapshots, but don't process it since it is pre-reset data
        mIgnoreNextExternalStats = true;
        mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET);
@@ -15761,6 +15765,16 @@ public class BatteryStatsImpl extends BatteryStats {
        mCpuPowerStatsCollector.forceSchedule();
    }
    /**
     * Schedules an immediate collection of PowerStats samples and awaits the result.
     */
    public void collectPowerStatsSamples() {
        schedulePowerStatsSampleCollection();
        ConditionVariable done = new ConditionVariable();
        mHandler.post(done::open);
        done.block();
    }
    /**
     * Grabs one sample of PowerStats and prints it.
     */
+13 −8
Original line number Diff line number Diff line
@@ -126,6 +126,10 @@ public class BatteryUsageStatsProvider {
     */
    public List<BatteryUsageStats> getBatteryUsageStats(BatteryStatsImpl stats,
            List<BatteryUsageStatsQuery> queries) {
        if (mPowerStatsExporterEnabled) {
            stats.collectPowerStatsSamples();
        }

        ArrayList<BatteryUsageStats> results = new ArrayList<>(queries.size());
        synchronized (stats) {
            stats.prepareForDumpLocked();
@@ -168,15 +172,16 @@ public class BatteryUsageStatsProvider {
                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0);
        final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold();

        final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
        final BatteryUsageStats.Builder batteryUsageStatsBuilder;
        synchronized (stats) {
            batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
                    stats.getCustomEnergyConsumerNames(), includePowerModels,
                    includeProcessStateData, minConsumedPowerThreshold);

            // TODO(b/188068523): use a monotonic clock to ensure resilience of order and duration
            // of batteryUsageStats sessions to wall-clock adjustments
            batteryUsageStatsBuilder.setStatsStartTimestamp(stats.getStartClockTime());
            batteryUsageStatsBuilder.setStatsEndTimestamp(currentTimeMs);

        synchronized (stats) {
            SparseArray<? extends BatteryStats.Uid> uidStats = stats.getUidStats();
            for (int i = uidStats.size() - 1; i >= 0; i--) {
                final BatteryStats.Uid uid = uidStats.valueAt(i);
+3 −1
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ public class PowerStatsExporter {
     */
    public void exportAggregatedPowerStats(BatteryUsageStats.Builder batteryUsageStatsBuilder,
            long monotonicStartTime, long monotonicEndTime) {
        boolean hasStoredSpans = false;
        long maxEndTime = monotonicStartTime;
        List<PowerStatsSpan.Metadata> spans = mPowerStatsStore.getTableOfContents();
        for (int i = spans.size() - 1; i >= 0; i--) {
@@ -99,13 +100,14 @@ public class PowerStatsExporter {
            }
            List<PowerStatsSpan.Section> sections = span.getSections();
            for (int k = 0; k < sections.size(); k++) {
                hasStoredSpans = true;
                PowerStatsSpan.Section section = sections.get(k);
                populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder,
                        ((AggregatedPowerStatsSection) section).getAggregatedPowerStats());
            }
        }

        if (maxEndTime < monotonicEndTime - mBatterySessionTimeSpanSlackMillis) {
        if (!hasStoredSpans || maxEndTime < monotonicEndTime - mBatterySessionTimeSpanSlackMillis) {
            mPowerStatsAggregator.aggregatePowerStats(maxEndTime, monotonicEndTime,
                    stats -> populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder, stats));
        }