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

Commit c8ce45dd authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Untangle circular dependency between BatteryStats and BatteryUsageStatsProvider

Bug: 302013436
Test: atest PowerStatsTests

Change-Id: Iea68a8d338174f6860027d01e20f91627333345a
parent bdb52a53
Loading
Loading
Loading
Loading
+29 −18
Original line number Diff line number Diff line
@@ -4028,6 +4028,17 @@ public abstract class BatteryStats {
        return false;
    }

    /**
     * A helper object passed to various dump... methods to integrate with such objects
     * as BatteryUsageStatsProvider.
     */
    public interface BatteryStatsDumpHelper {
        /**
         * Generates BatteryUsageStats based on the specified BatteryStats.
         */
        BatteryUsageStats getBatteryUsageStats(BatteryStats batteryStats, boolean detailed);
    }

    /**
     * Dumps the ControllerActivityCounter if it has any data worth dumping.
     * The order of the arguments in the final check in line is:
@@ -4390,7 +4401,7 @@ public abstract class BatteryStats {
     * NOTE: all times are expressed in microseconds, unless specified otherwise.
     */
    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
            boolean wifiOnly) {
            boolean wifiOnly, BatteryStatsDumpHelper dumpHelper) {

        if (which != BatteryStats.STATS_SINCE_CHARGED) {
            dumpLine(pw, 0, STAT_NAMES[which], "err",
@@ -4652,7 +4663,7 @@ public abstract class BatteryStats {
            }
        }

        final BatteryUsageStats stats = getBatteryUsageStats(context, true /* detailed */);
        final BatteryUsageStats stats = dumpHelper.getBatteryUsageStats(this, true /* detailed */);
        dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
                formatCharge(stats.getBatteryCapacity()),
                formatCharge(stats.getConsumedPower()),
@@ -5127,7 +5138,7 @@ public abstract class BatteryStats {

    @SuppressWarnings("unused")
    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
            int reqUid, boolean wifiOnly) {
            int reqUid, boolean wifiOnly, BatteryStatsDumpHelper dumpHelper) {

        if (which != BatteryStats.STATS_SINCE_CHARGED) {
            pw.println("ERROR: BatteryStats.dump called for which type " + which
@@ -5854,7 +5865,7 @@ public abstract class BatteryStats {
        pw.println();


        BatteryUsageStats stats = getBatteryUsageStats(context, true /* detailed */);
        BatteryUsageStats stats = dumpHelper.getBatteryUsageStats(this, true /* detailed */);
        stats.dump(pw, prefix);

        List<UidMobileRadioStats> uidMobileRadioStats =
@@ -7645,7 +7656,8 @@ public abstract class BatteryStats {
     * @param pw         a Printer to receive the dump output.
     */
    @SuppressWarnings("unused")
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart,
            BatteryStatsDumpHelper dumpHelper) {
        synchronized (this) {
            prepareForDumpLocked();
        }
@@ -7663,12 +7675,12 @@ public abstract class BatteryStats {
        }

        synchronized (this) {
            dumpLocked(context, pw, flags, reqUid, filtering);
            dumpLocked(context, pw, flags, reqUid, filtering, dumpHelper);
        }
    }

    private void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid,
            boolean filtering) {
            boolean filtering, BatteryStatsDumpHelper dumpHelper) {
        if (!filtering) {
            SparseArray<? extends Uid> uidStats = getUidStats();
            final int NU = uidStats.size();
@@ -7803,15 +7815,15 @@ public abstract class BatteryStats {
            pw.println("  System starts: " + getStartCount()
                    + ", currently on battery: " + getIsOnBattery());
            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0, dumpHelper);
            pw.println();
        }
    }

    // This is called from BatteryStatsService.
    @SuppressWarnings("unused")
    public void dumpCheckin(Context context, PrintWriter pw,
            List<ApplicationInfo> apps, int flags, long histStart) {
    public void dumpCheckin(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags,
            long histStart, BatteryStatsDumpHelper dumpHelper) {
        synchronized (this) {
            prepareForDumpLocked();

@@ -7829,12 +7841,12 @@ public abstract class BatteryStats {
        }

        synchronized (this) {
            dumpCheckinLocked(context, pw, apps, flags);
            dumpCheckinLocked(context, pw, apps, flags, dumpHelper);
        }
    }

    private void dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps,
            int flags) {
            int flags, BatteryStatsDumpHelper dumpHelper) {
        if (apps != null) {
            SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
            for (int i=0; i<apps.size(); i++) {
@@ -7881,7 +7893,7 @@ public abstract class BatteryStats {
                        (Object[])lineArgs);
            }
            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0, dumpHelper);
        }
    }

@@ -7891,7 +7903,7 @@ public abstract class BatteryStats {
     * @hide
     */
    public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
            int flags, long histStart) {
            int flags, long histStart, BatteryStatsDumpHelper dumpHelper) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);
        prepareForDumpLocked();

@@ -7909,7 +7921,8 @@ public abstract class BatteryStats {
        proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());

        if ((flags & DUMP_DAILY_ONLY) == 0) {
            final BatteryUsageStats stats = getBatteryUsageStats(context, false /* detailed */);
            final BatteryUsageStats stats =
                    dumpHelper.getBatteryUsageStats(this, false /* detailed */);
            ProportionalAttributionCalculator proportionalAttributionCalculator =
                    new ProportionalAttributionCalculator(context, stats);
            dumpProtoAppsLocked(proto, stats, apps, proportionalAttributionCalculator);
@@ -8856,8 +8869,6 @@ public abstract class BatteryStats {
        return !tm.isDataCapable();
    }

    protected abstract BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed);

    private boolean shouldHidePowerComponent(int powerComponent) {
        return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE
                || powerComponent == BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public class MonotonicClock {
    private final Clock mClock;
    private long mTimeshift;

    public static final long UNDEFINED = -1;

    public MonotonicClock(File file) {
        mFile = new AtomicFile(file);
        mClock = Clock.SYSTEM_CLOCK;
+19 −12
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ import com.android.server.pm.UserManagerInternal;
import com.android.server.power.optimization.Flags;
import com.android.server.power.stats.AggregatedPowerStatsConfig;
import com.android.server.power.stats.BatteryExternalStatsWorker;
import com.android.server.power.stats.BatteryStatsDumpHelperImpl;
import com.android.server.power.stats.BatteryStatsImpl;
import com.android.server.power.stats.BatteryUsageStatsProvider;
import com.android.server.power.stats.CpuAggregatedPowerStatsProcessor;
@@ -181,6 +182,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
    private final BatteryExternalStatsWorker mWorker;
    private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
    private final AtomicFile mConfigFile;
    private final BatteryStats.BatteryStatsDumpHelper mDumpHelper;

    private volatile boolean mMonitorEnabled = true;

@@ -419,8 +421,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub

        AggregatedPowerStatsConfig aggregatedPowerStatsConfig = getAggregatedPowerStatsConfig();
        mPowerStatsStore = new PowerStatsStore(systemDir, mHandler, aggregatedPowerStatsConfig);
        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats,
                mPowerStatsStore);
        mPowerStatsAggregator = new PowerStatsAggregator(aggregatedPowerStatsConfig,
                mStats.getHistory());
        final long aggregatedPowerStatsSpanDuration = context.getResources().getInteger(
@@ -429,7 +429,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                com.android.internal.R.integer.config_powerStatsAggregationPeriod);
        mPowerStatsScheduler = new PowerStatsScheduler(context, mPowerStatsAggregator,
                aggregatedPowerStatsSpanDuration, powerStatsAggregationPeriod, mPowerStatsStore,
                Clock.SYSTEM_CLOCK, mMonotonicClock, mHandler, mStats, mBatteryUsageStatsProvider);
                Clock.SYSTEM_CLOCK, mMonotonicClock, mHandler, mStats);
        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mPowerProfile,
                mCpuScalingPolicies, mPowerStatsStore, Clock.SYSTEM_CLOCK);
        mStats.saveBatteryUsageStatsOnReset(mBatteryUsageStatsProvider, mPowerStatsStore);
        mDumpHelper = new BatteryStatsDumpHelperImpl(mBatteryUsageStatsProvider);
        mCpuWakeupStats = new CpuWakeupStats(context, R.xml.irq_device_map, mHandler);
        mConfigFile = new AtomicFile(new File(systemDir, "battery_usage_stats_config"));
    }
@@ -877,12 +881,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub

        awaitCompletion();

        if (mBatteryUsageStatsProvider.shouldUpdateStats(queries,
        if (BatteryUsageStatsProvider.shouldUpdateStats(queries,
                SystemClock.elapsedRealtime(),
                mWorker.getLastCollectionTimeStamp())) {
            syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
        }

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

    /** Register callbacks for statsd pulled atoms. */
@@ -2723,7 +2730,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
        synchronized (mStats) {
            mStats.prepareForDumpLocked();
            BatteryUsageStats batteryUsageStats =
                    mBatteryUsageStatsProvider.getBatteryUsageStats(query);
                    mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, query);
            if (proto) {
                batteryUsageStats.dumpToProto(fd);
            } else {
@@ -3011,8 +3018,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                                        mCpuScalingPolicies);
                                checkinStats.readSummaryFromParcel(in);
                                in.recycle();
                                checkinStats.dumpProtoLocked(
                                        mContext, fd, apps, flags, historyStart);
                                checkinStats.dumpProtoLocked(mContext, fd, apps, flags,
                                        historyStart, mDumpHelper);
                                mStats.mCheckinFile.delete();
                                return;
                            }
@@ -3026,7 +3033,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
            awaitCompletion();
            synchronized (mStats) {
                mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart);
                mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart, mDumpHelper);
                if (writeData) {
                    mStats.writeAsyncLocked();
                }
@@ -3054,7 +3061,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                                checkinStats.readSummaryFromParcel(in);
                                in.recycle();
                                checkinStats.dumpCheckin(mContext, pw, apps, flags,
                                        historyStart);
                                        historyStart, mDumpHelper);
                                mStats.mCheckinFile.delete();
                                return;
                            }
@@ -3067,7 +3074,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            }
            if (DBG) Slog.d(TAG, "begin dumpCheckin from UID " + Binder.getCallingUid());
            awaitCompletion();
            mStats.dumpCheckin(mContext, pw, apps, flags, historyStart);
            mStats.dumpCheckin(mContext, pw, apps, flags, historyStart, mDumpHelper);
            if (writeData) {
                mStats.writeAsyncLocked();
            }
@@ -3076,7 +3083,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            if (DBG) Slog.d(TAG, "begin dump from UID " + Binder.getCallingUid());
            awaitCompletion();

            mStats.dump(mContext, pw, flags, reqUid, historyStart);
            mStats.dump(mContext, pw, flags, reqUid, historyStart, mDumpHelper);
            if (writeData) {
                mStats.writeAsyncLocked();
            }
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.power.stats;

import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;

public class BatteryStatsDumpHelperImpl implements BatteryStats.BatteryStatsDumpHelper {
    private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;

    public BatteryStatsDumpHelperImpl(BatteryUsageStatsProvider batteryUsageStatsProvider) {
        mBatteryUsageStatsProvider = batteryUsageStatsProvider;
    }

    @Override
    public BatteryUsageStats getBatteryUsageStats(BatteryStats batteryStats, boolean detailed) {
        BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder()
                .setMaxStatsAgeMs(0);
        if (detailed) {
            builder.includePowerModels().includeProcessStateData().includeVirtualUids();
        }
        return mBatteryUsageStatsProvider.getBatteryUsageStats((BatteryStatsImpl) batteryStats,
                builder.build());
    }
}
+101 −61
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ public class BatteryStatsImpl extends BatteryStats {
    // TODO: remove "tcp" from network methods, since we measure total stats.
    // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
    public static final int VERSION = 213;
    public static final int VERSION = 214;
    // The maximum number of names wakelocks we will keep track of
    // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -220,6 +220,8 @@ public class BatteryStatsImpl extends BatteryStats {
    public static final int RESET_REASON_FULL_CHARGE = 3;
    public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4;
    public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5;
    @NonNull
    private final MonotonicClock mMonotonicClock;
    protected Clock mClock;
@@ -393,19 +395,9 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }
    /**
     * Listener for the battery stats reset.
     */
    public interface BatteryResetListener {
        /**
         * Callback invoked immediately prior to resetting battery stats.
         * @param resetReason One of the RESET_REASON_* constants.
         */
        void prepareForBatteryStatsReset(int resetReason);
    }
    private BatteryResetListener mBatteryResetListener;
    private boolean mSaveBatteryUsageStatsOnReset;
    private BatteryUsageStatsProvider mBatteryUsageStatsProvider;
    private PowerStatsStore mPowerStatsStore;
    public interface BatteryCallback {
        public void batteryNeedsCpuUpdate();
@@ -874,6 +866,8 @@ public class BatteryStatsImpl extends BatteryStats {
    long mUptimeStartUs;
    long mRealtimeUs;
    long mRealtimeStartUs;
    long mMonotonicStartTime;
    long mMonotonicEndTime = MonotonicClock.UNDEFINED;
    int mWakeLockNesting;
    boolean mWakeLockImportant;
@@ -1731,18 +1725,17 @@ public class BatteryStatsImpl extends BatteryStats {
        mConstants = new Constants(mHandler);
        mStartClockTimeMs = clock.currentTimeMillis();
        mDailyFile = null;
        mMonotonicClock = new MonotonicClock(0, mClock);
        if (historyDirectory == null) {
            mCheckinFile = null;
            mStatsFile = null;
            mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES,
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock,
                    new MonotonicClock(0, mClock));
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
        } else {
            mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin"));
            mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
            mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES,
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock,
                    new MonotonicClock(0, mClock));
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
        }
        mPlatformIdleStateCallback = null;
        mEnergyConsumerRetriever = null;
@@ -7642,9 +7635,9 @@ public class BatteryStatsImpl extends BatteryStats {
    /**
     * Returns the names of custom power components.
     */
    @GuardedBy("this")
    @Override
    public @NonNull String[] getCustomEnergyConsumerNames() {
        synchronized (this) {
            if (mEnergyConsumerStatsConfig == null) {
                return new String[0];
            }
@@ -7656,9 +7649,11 @@ public class BatteryStatsImpl extends BatteryStats {
            }
            return names;
        }
    }
    @GuardedBy("this")
    @Override public long getStartClockTime() {
    @Override
    public long getStartClockTime() {
        synchronized (this) {
            final long currentTimeMs = mClock.currentTimeMillis();
            if ((currentTimeMs > MILLISECONDS_IN_YEAR
                    && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR))
@@ -7672,6 +7667,22 @@ public class BatteryStatsImpl extends BatteryStats {
            }
            return mStartClockTimeMs;
        }
    }
    /**
     * Returns the monotonic time when the BatteryStats session started.
     */
    public long getMonotonicStartTime() {
        return mMonotonicStartTime;
    }
    /**
     * Returns the monotonic time when the BatteryStats session ended, or
     * {@link MonotonicClock#UNDEFINED} if the session is still ongoing.
     */
    public long getMonotonicEndTime() {
        return mMonotonicEndTime;
    }
    @Override public String getStartPlatformVersion() {
        return mStartPlatformVersion;
@@ -10914,6 +10925,7 @@ public class BatteryStatsImpl extends BatteryStats {
        init(clock);
        mBatteryStatsConfig = config;
        mMonotonicClock = monotonicClock;
        mHandler = new MyHandler(handler.getLooper());
        mConstants = new Constants(mHandler);
@@ -10927,13 +10939,13 @@ public class BatteryStatsImpl extends BatteryStats {
            mCheckinFile = null;
            mDailyFile = null;
            mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES,
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, monotonicClock);
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
        } else {
            mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin"));
            mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
            mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
            mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES,
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, monotonicClock);
                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
        }
        mCpuPowerStatsCollector = new CpuPowerStatsCollector(mCpuScalingPolicies, mPowerProfile,
@@ -11497,6 +11509,7 @@ public class BatteryStatsImpl extends BatteryStats {
        mUptimeUs = 0;
        mRealtimeStartUs = realtimeUs;
        mUptimeStartUs = uptimeUs;
        mMonotonicStartTime = mMonotonicClock.monotonicTime();
    }
    void initDischarge(long elapsedRealtimeUs) {
@@ -11517,8 +11530,17 @@ public class BatteryStatsImpl extends BatteryStats {
        mDischargeCounter.reset(false, elapsedRealtimeUs);
    }
    public void setBatteryResetListener(BatteryResetListener batteryResetListener) {
        mBatteryResetListener = batteryResetListener;
    /**
     * Associates the BatteryStatsImpl object with a BatteryUsageStatsProvider and PowerStatsStore
     * to allow for a snapshot of battery usage stats to be taken and stored just before battery
     * reset.
     */
    public void saveBatteryUsageStatsOnReset(
            @NonNull BatteryUsageStatsProvider batteryUsageStatsProvider,
            @NonNull PowerStatsStore powerStatsStore) {
        mSaveBatteryUsageStatsOnReset = true;
        mBatteryUsageStatsProvider = batteryUsageStatsProvider;
        mPowerStatsStore = powerStatsStore;
    }
    @GuardedBy("this")
@@ -11557,9 +11579,7 @@ public class BatteryStatsImpl extends BatteryStats {
    @GuardedBy("this")
    private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis,
            int resetReason) {
        if (mBatteryResetListener != null) {
            mBatteryResetListener.prepareForBatteryStatsReset(resetReason);
        }
        saveBatteryUsageStatsOnReset(resetReason);
        final long uptimeUs = uptimeMillis * 1000;
        final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000;
@@ -11707,6 +11727,31 @@ public class BatteryStatsImpl extends BatteryStats {
        mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS);
    }
    private void saveBatteryUsageStatsOnReset(int resetReason) {
        if (!mSaveBatteryUsageStatsOnReset
                || resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) {
            return;
        }
        final BatteryUsageStats batteryUsageStats;
        synchronized (this) {
            batteryUsageStats = mBatteryUsageStatsProvider.getBatteryUsageStats(this,
                    new BatteryUsageStatsQuery.Builder()
                            .setMaxStatsAgeMs(0)
                            .includePowerModels()
                            .includeProcessStateData()
                            .build());
        }
        // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end
        // Once that change is made, we will be able to use the BatteryUsageStats' monotonic
        // start time
        long monotonicStartTime =
                mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration();
        mHandler.post(() ->
                mPowerStatsStore.storeBatteryUsageStats(monotonicStartTime, batteryUsageStats));
    }
    @GuardedBy("this")
    private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
@@ -15192,11 +15237,12 @@ public class BatteryStatsImpl extends BatteryStats {
        mShuttingDown = true;
    }
    @GuardedBy("this")
    @Override
    public boolean isProcessStateDataAvailable() {
        synchronized (this) {
            return trackPerProcStateCpuTimes();
        }
    }
    @GuardedBy("this")
    private boolean trackPerProcStateCpuTimes() {
@@ -15862,6 +15908,8 @@ public class BatteryStatsImpl extends BatteryStats {
        mUptimeUs = in.readLong();
        mRealtimeUs = in.readLong();
        mStartClockTimeMs = in.readLong();
        mMonotonicStartTime = in.readLong();
        mMonotonicEndTime = in.readLong();
        mStartPlatformVersion = in.readString();
        mEndPlatformVersion = in.readString();
        mOnBatteryTimeBase.readSummaryFromParcel(in);
@@ -16382,6 +16430,8 @@ public class BatteryStatsImpl extends BatteryStats {
        out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED));
        out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED));
        out.writeLong(mStartClockTimeMs);
        out.writeLong(mMonotonicStartTime);
        out.writeLong(mMonotonicClock.monotonicTime());
        out.writeString(mStartPlatformVersion);
        out.writeString(mEndPlatformVersion);
        mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime);
@@ -16912,7 +16962,8 @@ public class BatteryStatsImpl extends BatteryStats {
    }
    @GuardedBy("this")
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart,
            BatteryStatsDumpHelper dumpHelper) {
        if (DEBUG) {
            pw.println("mOnBatteryTimeBase:");
            mOnBatteryTimeBase.dump(pw, "  ");
@@ -16984,7 +17035,7 @@ public class BatteryStatsImpl extends BatteryStats {
            pr.println("*** Camera timer:");
            mCameraOnTimer.logState(pr, "  ");
        }
        super.dump(context, pw, flags, reqUid, histStart);
        super.dump(context, pw, flags, reqUid, histStart, dumpHelper);
        synchronized (this) {
            pw.print("Per process state tracking available: ");
@@ -17020,15 +17071,4 @@ public class BatteryStatsImpl extends BatteryStats {
            dumpEnergyConsumerStatsLocked(pw);
        }
    }
    @Override
    protected BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed) {
        final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
        BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder()
                .setMaxStatsAgeMs(0);
        if (detailed) {
            builder.includePowerModels().includeProcessStateData().includeVirtualUids();
        }
        return provider.getBatteryUsageStats(builder.build());
    }
}
Loading