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

Commit 6d6e8186 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Address some out-of-order battery history event timestamps

Bug: 407828438
Test: atest PowerStatsTests
Flag: EXEMPT bug fix

Change-Id: Iefb6a273194982bac1aa73526c25ac906fc8262f
parent 516e13f8
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -6711,6 +6711,8 @@ public abstract class BatteryStats {
        // This constant MUST be incremented whenever the history dump format changes.
        private static final int FORMAT_VERSION = 2;

        private static final boolean DEBUG_TIMELINE = false;

        private final boolean mPerformanceBaseline;
        private final HistoryLogTimeFormatter mHistoryLogTimeFormatter;
        private final SimpleDateFormat mHistoryItemTimestampFormat;
@@ -6811,6 +6813,12 @@ public abstract class BatteryStats {
                    } else {
                        mHistoryLogTimeFormatter.append(item, rec.currentTime);
                        item.append(' ');
                        if (DEBUG_TIMELINE) {
                            if (rec.time < lastTime) {
                                item.append("[Earlier timestamp by ")
                                        .append(rec.time - lastTime).append("] ");
                            }
                        }
                    }
                }
            } else {
@@ -6821,8 +6829,8 @@ public abstract class BatteryStats {
                } else {
                    item.append(rec.time - lastTime);
                }
                lastTime = rec.time;
            }
            lastTime = rec.time;
            if (rec.cmd == HistoryItem.CMD_START) {
                if (checkin) {
                    item.append(":");
+329 −325

File changed.

Preview size limit exceeded, changes collapsed.

+78 −75
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.os.Handler;
import android.os.OutcomeReceiver;
import android.os.Parcelable;
import android.os.SynchronousResultReceiver;
import android.os.SystemClock;
import android.os.connectivity.WifiActivityEnergyInfo;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
@@ -36,6 +35,7 @@ import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.Clock;
import com.android.server.LocalServices;

import java.util.concurrent.CompletableFuture;
@@ -80,6 +80,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
    private static final int SYNC_USER_REMOVAL = 5;

    private final Handler mHandler;
    private final Clock mClock;

    @GuardedBy("mStats")
    private final BatteryStatsImpl mStats;
@@ -122,7 +123,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat

    /**
     * Timestamp at which all external stats were last collected in
     * {@link SystemClock#elapsedRealtime()} time base.
     * {@link Clock#elapsedRealtime()} time base.
     */
    @GuardedBy("this")
    private long mLastCollectionTimeStamp;
@@ -146,15 +147,18 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
        }
    }

    public BatteryExternalStatsWorker(Context context, BatteryStatsImpl stats, Handler handler) {
        this(new Injector(context), stats, handler);
    public BatteryExternalStatsWorker(Context context, BatteryStatsImpl stats, Handler handler,
            Clock clock) {
        this(new Injector(context), stats, handler, clock);
    }

    @VisibleForTesting
    BatteryExternalStatsWorker(Injector injector, BatteryStatsImpl stats, Handler handler) {
    BatteryExternalStatsWorker(Injector injector, BatteryStatsImpl stats, Handler handler,
            Clock clock) {
        mInjector = injector;
        mStats = stats;
        mHandler = handler;
        mClock = clock;
    }

    public void systemServicesReady() {
@@ -301,7 +305,11 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
        if (!mHandler.hasMessages(SYNC_UPDATE)) {
            mUpdateFlags = flags;
            mCurrentReason = reason;
            mHandler.postDelayed(mSyncTask, SYNC_UPDATE, 0);
            synchronized (mClock) {
                long elapsedRealtimeMs = mClock.elapsedRealtime();
                long uptimeMs = mClock.uptimeMillis();
                mHandler.postDelayed(() -> sync(elapsedRealtimeMs, uptimeMs), SYNC_UPDATE, 0);
            }
        }
        mUpdateFlags |= flags;
    }
@@ -312,9 +320,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
        }
    }

    private final Runnable mSyncTask = new Runnable() {
        @Override
        public void run() {
    private void sync(long elapsedRealtimeMs, long uptimeMs) {
        // Capture a snapshot of the state we are meant to process.
        final int updateFlags;
        final String reason;
@@ -353,7 +359,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
                try {
                    updateExternalStatsLocked(reason, updateFlags, onBattery,
                            onBatteryScreenOff, screenState, displayScreenStates,
                                useLatestStates);
                            useLatestStates, elapsedRealtimeMs, uptimeMs);
                } finally {
                    if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) {
                        synchronized (mStats) {
@@ -385,8 +391,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
            }
        } else if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) {
            synchronized (BatteryExternalStatsWorker.this) {
                    mLastCollectionTimeStamp = SystemClock.elapsedRealtime();
                }
                mLastCollectionTimeStamp = elapsedRealtimeMs;
            }
        }
    };
@@ -403,7 +408,7 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
    @GuardedBy("mWorkerLock")
    private void updateExternalStatsLocked(final String reason, int updateFlags, boolean onBattery,
            boolean onBatteryScreenOff, int screenState, int[] displayScreenStates,
            boolean useLatestStates) {
            boolean useLatestStates, long elapsedRealtime, long uptime) {
        // We will request data from external processes asynchronously, and wait on a timeout.
        SynchronousResultReceiver wifiReceiver = null;
        SynchronousResultReceiver bluetoothReceiver = null;
@@ -528,8 +533,6 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
            Slog.w(TAG, "exception reading modem stats: " + e.getCause());
        }

        final long elapsedRealtime = SystemClock.elapsedRealtime();
        final long uptime = SystemClock.uptimeMillis();
        final long elapsedRealtimeUs = elapsedRealtime * 1000;
        final long uptimeUs = uptime * 1000;

+23 −9
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.power.PowerStatsInternal;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.os.Clock;
import com.android.server.LocalServices;

import java.util.HashMap;
@@ -42,6 +43,7 @@ class BatteryHistoryStepDetailsProvider {
    private final BatteryStatsImpl mBatteryStats;

    private final BatteryStats.HistoryStepDetails mDetails = new BatteryStats.HistoryStepDetails();
    private final Clock mClock;

    private boolean mHasHistoryStepDetails;

@@ -78,10 +80,11 @@ class BatteryHistoryStepDetailsProvider {
    private Map<Integer, Map<Integer, String>> mStateNames;

    private boolean mFirstUpdate = true;
    private final Runnable mUpdateRunnable = this::update;
    private final Object mUpdateToken = new Object();

    BatteryHistoryStepDetailsProvider(BatteryStatsImpl batteryStats) {
    BatteryHistoryStepDetailsProvider(BatteryStatsImpl batteryStats, Clock clock) {
        mBatteryStats = batteryStats;
        mClock = clock;
    }

    void onSystemReady() {
@@ -89,22 +92,33 @@ class BatteryHistoryStepDetailsProvider {
    }

    void requestUpdate() {
        mBatteryStats.mHandler.removeCallbacks(mUpdateRunnable);
        mBatteryStats.mHandler.removeCallbacksAndMessages(mUpdateToken);
        if (!mSystemReady || mFirstUpdate) {
            mBatteryStats.mHandler.postDelayed(mUpdateRunnable, BOOT_TIME_UPDATE_DELAY_MILLIS);
            // System is busy; schedule an update at a later time.
            mBatteryStats.mHandler.postDelayed(() -> {
                synchronized (mClock) {
                    long elapsedRealtimeMs = mClock.elapsedRealtime();
                    long uptimeMs = mClock.uptimeMillis();
                    update(elapsedRealtimeMs, uptimeMs);
                }
            }, mUpdateToken, BOOT_TIME_UPDATE_DELAY_MILLIS);
        } else {
            mBatteryStats.mHandler.post(mUpdateRunnable);
            synchronized (mClock) {
                // Grab the timestamp before posting to the handler to keep the timeline consistent
                long elapsedRealtimeMs = mClock.elapsedRealtime();
                long uptimeMs = mClock.uptimeMillis();
                mBatteryStats.mHandler.postDelayed(() -> update(elapsedRealtimeMs, uptimeMs),
                        mUpdateToken, 0);
            }
        }
    }

    void update() {
    void update(long elapsedRealtimeMs, long uptimeMs) {
        mHasHistoryStepDetails = false;
        mBatteryStats.updateCpuDetails();
        calculateHistoryStepDetails();
        updateStateResidency();
        mBatteryStats.getHistory().recordHistoryStepDetails(mDetails,
                mBatteryStats.mClock.elapsedRealtime(),
                mBatteryStats.mClock.uptimeMillis());
        mBatteryStats.getHistory().recordHistoryStepDetails(mDetails, elapsedRealtimeMs, uptimeMs);
        mFirstUpdate = false;
    }

+5 −4
Original line number Diff line number Diff line
@@ -1122,8 +1122,7 @@ public class BatteryStatsImpl extends BatteryStats {
    private boolean mShuttingDown;
    private final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
    private final BatteryHistoryStepDetailsProvider mStepDetailsProvider =
            new BatteryHistoryStepDetailsProvider(this);
    private final BatteryHistoryStepDetailsProvider mStepDetailsProvider;
    private boolean mHaveBatteryLevel = false;
    private boolean mBatteryPluggedIn;
@@ -10769,6 +10768,8 @@ public class BatteryStatsImpl extends BatteryStats {
        mPowerStatsUidResolver = powerStatsUidResolver;
        mFrameworkStatsLogger = frameworkStatsLogger;
        mStepDetailsProvider = new BatteryHistoryStepDetailsProvider(this, clock);
        initPowerProfile();
        if (systemDir != null) {
@@ -10852,10 +10853,10 @@ public class BatteryStatsImpl extends BatteryStats {
        mFrameworkStatsLogger.deviceIdleModeStateChanged(mDeviceIdleMode);
    }
    private void recordPowerStats(PowerStats stats) {
    private void recordPowerStats(PowerStats stats, long elapsedRealtimeMs, long uptimeMs) {
        if (stats.durationMs > 0) {
            synchronized (this) {
                mHistory.recordPowerStats(mClock.elapsedRealtime(), mClock.uptimeMillis(), stats);
                mHistory.recordPowerStats(elapsedRealtimeMs, uptimeMs, stats);
            }
        }
    }
Loading