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

Commit 5023847f authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Dump battery history without locking"

parents 59130bd0 e966996e
Loading
Loading
Loading
Loading
+32 −27
Original line number Diff line number Diff line
@@ -2425,8 +2425,9 @@ public abstract class BatteryStats {
    public abstract int getHistoryTagPoolUid(int index);

    /**
     * Returns a BatteryStatsHistoryIterator. Battery history will remain immutable until the
     * {@link BatteryStatsHistoryIterator#close()} method is invoked.
     * Returns a BatteryStatsHistoryIterator. Battery history will continue being writable,
     * but the iterator will continue iterating over the snapshot taken at the time this method
     * is called.
     */
    public abstract BatteryStatsHistoryIterator iterateBatteryStatsHistory();

@@ -5120,14 +5121,6 @@ public abstract class BatteryStats {
        sb.append(formatCharge(power));
    }

    /**
     * Temporary for settings.
     */
    public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
            int reqUid) {
        dumpLocked(context, pw, prefix, which, reqUid, checkWifiOnly(context));
    }

    @SuppressWarnings("unused")
    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
            int reqUid, boolean wifiOnly) {
@@ -7483,7 +7476,25 @@ public abstract class BatteryStats {
    public static final int DUMP_VERBOSE = 1<<5;
    public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;

    private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
    private void dumpHistory(PrintWriter pw, int flags, long histStart, boolean checkin) {
        if (!checkin) {
            synchronized (this) {
                final long historyTotalSize = getHistoryTotalSize();
                final long historyUsedSize = getHistoryUsedSize();
                pw.print("Battery History (");
                pw.print((100 * historyUsedSize) / historyTotalSize);
                pw.print("% used, ");
                printSizeValue(pw, historyUsedSize);
                pw.print(" used of ");
                printSizeValue(pw, historyTotalSize);
                pw.print(", ");
                pw.print(getHistoryStringPoolSize());
                pw.print(" strings using ");
                printSizeValue(pw, getHistoryStringPoolBytes());
                pw.println("):");
            }
        }

        final HistoryPrinter hprinter = new HistoryPrinter();
        long lastTime = -1;
        long baseTime = -1;
@@ -7628,27 +7639,14 @@ public abstract class BatteryStats {
     * @param pw a Printer to receive the dump output.
     */
    @SuppressWarnings("unused")
    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
        prepareForDumpLocked();

        final boolean filtering = (flags
                & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;

        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
            final long historyTotalSize = getHistoryTotalSize();
            final long historyUsedSize = getHistoryUsedSize();
            pw.print("Battery History (");
            pw.print((100 * historyUsedSize) / historyTotalSize);
            pw.print("% used, ");
            printSizeValue(pw, historyUsedSize);
            pw.print(" used of ");
            printSizeValue(pw, historyTotalSize);
            pw.print(", ");
            pw.print(getHistoryStringPoolSize());
            pw.print(" strings using ");
            printSizeValue(pw, getHistoryStringPoolBytes());
            pw.println("):");
            dumpHistoryLocked(pw, flags, histStart, false);
            dumpHistory(pw, flags, histStart, false);
            pw.println();
        }

@@ -7656,6 +7654,13 @@ public abstract class BatteryStats {
            return;
        }

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

    private void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid,
            boolean filtering) {
        if (!filtering) {
            SparseArray<? extends Uid> uidStats = getUidStats();
            final int NU = uidStats.size();
@@ -7823,7 +7828,7 @@ public abstract class BatteryStats {
                }
                pw.print("\"");
                pw.println();
                dumpHistoryLocked(pw, flags, histStart, true);
                dumpHistory(pw, flags, histStart, true);
            }
        }

+96 −38
Original line number Diff line number Diff line
@@ -40,12 +40,12 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ParseUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -198,6 +198,8 @@ public class BatteryStatsHistory {
    private final VarintParceler mVarintParceler = new VarintParceler();
    private byte mLastHistoryStepLevel = 0;
    private boolean mMutable = true;
    private final BatteryStatsHistory mWritableHistory;
    private boolean mCleanupEnabled = true;

    /**
     * A delegate responsible for computing additional details for a step in battery history.
@@ -272,10 +274,32 @@ public class BatteryStatsHistory {
        initHistoryBuffer();
    }

    /**
     * Creates a read-only wrapper for the supplied writable history.
     */
    public BatteryStatsHistory(BatteryStatsHistory writableHistory) {
        this(Parcel.obtain(), writableHistory.mSystemDir, 0, 0, null, null, null, writableHistory);
        mMutable = false;

        synchronized (mWritableHistory) {
            // Make a copy of battery history to avoid concurrent modification.
            mHistoryBuffer.appendFrom(mWritableHistory.mHistoryBuffer, 0,
                    mWritableHistory.mHistoryBuffer.dataSize());
        }
    }

    @VisibleForTesting
    public BatteryStatsHistory(Parcel historyBuffer, File systemDir,
            int maxHistoryFiles, int maxHistoryBufferSize,
            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, TraceDelegate tracer) {
        this(historyBuffer, systemDir, maxHistoryFiles, maxHistoryBufferSize, stepDetailsCalculator,
                clock, tracer, null);
    }

    private BatteryStatsHistory(Parcel historyBuffer, File systemDir,
            int maxHistoryFiles, int maxHistoryBufferSize,
            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock, TraceDelegate tracer,
            BatteryStatsHistory writableHistory) {
        mHistoryBuffer = historyBuffer;
        mSystemDir = systemDir;
        mMaxHistoryFiles = maxHistoryFiles;
@@ -283,6 +307,7 @@ public class BatteryStatsHistory {
        mStepDetailsCalculator = stepDetailsCalculator;
        mTracer = tracer;
        mClock = clock;
        mWritableHistory = writableHistory;

        mHistoryDir = new File(systemDir, HISTORY_DIR);
        mHistoryDir.mkdirs();
@@ -292,22 +317,18 @@ public class BatteryStatsHistory {

        final Set<Integer> dedup = new ArraySet<>();
        // scan directory, fill mFileNumbers and mActiveFile.
        mHistoryDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
        mHistoryDir.listFiles((dir, name) -> {
            final int b = name.lastIndexOf(FILE_SUFFIX);
            if (b <= 0) {
                return false;
            }
                final Integer c =
                        ParseUtils.parseInt(name.substring(0, b), -1);
            final int c = ParseUtils.parseInt(name.substring(0, b), -1);
            if (c != -1) {
                dedup.add(c);
                return true;
            } else {
                return false;
            }
            }
        });
        if (!dedup.isEmpty()) {
            mFileNumbers.addAll(dedup);
@@ -328,21 +349,29 @@ public class BatteryStatsHistory {
        mHistoryBuffer = Parcel.obtain();
        mSystemDir = null;
        mHistoryDir = null;
        mWritableHistory = null;
        initHistoryBuffer();
    }

    /**
     * Used when BatteryStatsImpl object is created from deserialization of a parcel,
     * such as a checkin file.
     * Used when BatteryStatsHistory object is created from deserialization of a BatteryUsageStats
     * parcel.
     */
    private BatteryStatsHistory(Parcel historyBuffer,
            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
        mHistoryBuffer = historyBuffer;
        mTracer = new TraceDelegate();
        mClock = clock;
    private BatteryStatsHistory(Parcel parcel) {
        mClock = Clock.SYSTEM_CLOCK;
        mTracer = null;
        mSystemDir = null;
        mHistoryDir = null;
        mStepDetailsCalculator = stepDetailsCalculator;
        mStepDetailsCalculator = null;
        mWritableHistory = null;
        mMutable = false;

        final byte[] historyBlob = parcel.readBlob();

        mHistoryBuffer = Parcel.obtain();
        mHistoryBuffer.unmarshall(historyBlob, 0, historyBlob.length);

        readFromParcel(parcel, true /* useBlobs */);
    }

    private void initHistoryBuffer() {
@@ -386,10 +415,7 @@ public class BatteryStatsHistory {
     * in the system directory, so it is not safe while actively writing history.
     */
    public BatteryStatsHistory copy() {
        // Make a copy of battery history to avoid concurrent modification.
        Parcel historyBuffer = Parcel.obtain();
        historyBuffer.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
        return new BatteryStatsHistory(historyBuffer, mSystemDir, 0, 0, null, null, mTracer);
        return new BatteryStatsHistory(this);
    }

    /**
@@ -448,6 +474,25 @@ public class BatteryStatsHistory {
            Slog.e(TAG, "Could not create history file: " + mActiveFile.getBaseFile());
        }

        synchronized (this) {
            cleanupLocked();
        }
    }

    @GuardedBy("this")
    private void setCleanupEnabledLocked(boolean enabled) {
        mCleanupEnabled = enabled;
        if (mCleanupEnabled) {
            cleanupLocked();
        }
    }

    @GuardedBy("this")
    private void cleanupLocked() {
        if (!mCleanupEnabled || mHistoryDir == null) {
            return;
        }

        // if free disk space is less than 100MB, delete oldest history file.
        if (!hasFreeDiskSpace()) {
            int oldest = mFileNumbers.remove(0);
@@ -464,6 +509,16 @@ public class BatteryStatsHistory {
        }
    }

    /**
     * Returns true if it is safe to reset history. It will return false if the history is
     * currently being read.
     */
    public boolean isResetEnabled() {
        synchronized (this) {
            return mCleanupEnabled;
        }
    }

    /**
     * Clear history buffer and delete all existing history files. Active history file start from
     * number 0 again.
@@ -491,6 +546,11 @@ public class BatteryStatsHistory {
        mCurrentParcelEnd = 0;
        mParcelIndex = 0;
        mMutable = false;
        if (mWritableHistory != null) {
            synchronized (mWritableHistory) {
                mWritableHistory.setCleanupEnabledLocked(false);
            }
        }
        return new BatteryStatsHistoryIterator(this);
    }

@@ -500,8 +560,14 @@ public class BatteryStatsHistory {
    void iteratorFinished() {
        // setDataPosition so mHistoryBuffer Parcel can be written.
        mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
        if (mWritableHistory != null) {
            synchronized (mWritableHistory) {
                mWritableHistory.setCleanupEnabledLocked(true);
            }
        } else {
            mMutable = true;
        }
    }

    /**
     * When iterating history files and history buffer, always start from the lowest numbered
@@ -717,15 +783,7 @@ public class BatteryStatsHistory {
     * the {@link #writeToBatteryUsageStatsParcel} method.
     */
    public static BatteryStatsHistory createFromBatteryUsageStatsParcel(Parcel in) {
        final byte[] historyBlob = in.readBlob();

        Parcel historyBuffer = Parcel.obtain();
        historyBuffer.unmarshall(historyBlob, 0, historyBlob.length);

        BatteryStatsHistory history = new BatteryStatsHistory(historyBuffer, null,
                Clock.SYSTEM_CLOCK);
        history.readFromParcel(in, true /* useBlobs */);
        return history;
        return new BatteryStatsHistory(in);
    }

    /**
+3 −5
Original line number Diff line number Diff line
@@ -2905,12 +2905,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
            awaitCompletion();

            synchronized (mStats) {
                mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
            mStats.dump(mContext, pw, flags, reqUid, historyStart);
            if (writeData) {
                mStats.writeAsyncLocked();
            }
            }
            pw.println();
            mCpuWakeupStats.dump(new IndentingPrintWriter(pw, "  "), SystemClock.elapsedRealtime());

+35 −31
Original line number Diff line number Diff line
@@ -11299,7 +11299,7 @@ public class BatteryStatsImpl extends BatteryStats {
     */
    @Override
    public BatteryStatsHistoryIterator iterateBatteryStatsHistory() {
        return mHistory.iterate();
        return mHistory.copy().iterate();
    }
    @Override
@@ -14054,7 +14054,8 @@ public class BatteryStatsImpl extends BatteryStats {
                    && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
                    || level >= 90
                    || (mDischargeCurrentLevel < 20 && level >= 80)
                    || getHighDischargeAmountSinceCharge() >= 200)) {
                    || getHighDischargeAmountSinceCharge() >= 200)
                    && mHistory.isResetEnabled()) {
                Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
                        + " dischargeLevel=" + mDischargeCurrentLevel
                        + " lowAmount=" + getLowDischargeAmountSinceCharge()
@@ -16604,7 +16605,7 @@ public class BatteryStatsImpl extends BatteryStats {
    }
    @GuardedBy("this")
    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
        if (DEBUG) {
            pw.println("mOnBatteryTimeBase:");
            mOnBatteryTimeBase.dump(pw, "  ");
@@ -16676,8 +16677,9 @@ public class BatteryStatsImpl extends BatteryStats {
            pr.println("*** Camera timer:");
            mCameraOnTimer.logState(pr, "  ");
        }
        super.dumpLocked(context, pw, flags, reqUid, histStart);
        super.dump(context, pw, flags, reqUid, histStart);
        synchronized (this) {
            pw.print("Per process state tracking available: ");
            pw.println(trackPerProcStateCpuTimes());
            pw.print("Total cpu time reads: ");
@@ -16695,7 +16697,8 @@ public class BatteryStatsImpl extends BatteryStats {
                final int isolatedUid = mIsolatedUids.keyAt(i);
                final int ownerUid = mIsolatedUids.valueAt(i);
                final int refCount = mIsolatedUidRefCounts.get(isolatedUid);
            pw.println("  " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")");
                pw.println(
                        "  " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")");
            }
            pw.println();
@@ -16707,6 +16710,7 @@ public class BatteryStatsImpl extends BatteryStats {
            pw.println();
            dumpEnergyConsumerStatsLocked(pw);
        }
    }
    @Override
    protected BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed) {