diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 09a52e4..da20626 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2326,11 +2326,6 @@
     public abstract void finishIteratingHistoryLocked();
 
     /**
-     * Return the base time offset for the battery history.
-     */
-    public abstract long getHistoryBaseTime();
-
-    /**
      * Returns the number of times the device has been started.
      */
     public abstract int getStartCount();
@@ -7615,8 +7610,6 @@
                 CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
                 getEndPlatformVersion());
 
-        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
-
         if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
             if (startIteratingHistoryLocked()) {
                 try {
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 962870e..6909965 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -17,25 +17,35 @@
 package com.android.internal.os;
 
 import android.annotation.Nullable;
-import android.os.BatteryStats;
+import android.os.BatteryManager;
+import android.os.BatteryStats.HistoryItem;
+import android.os.BatteryStats.HistoryStepDetails;
+import android.os.BatteryStats.HistoryTag;
 import android.os.Parcel;
+import android.os.ParcelFormatException;
+import android.os.Process;
 import android.os.StatFs;
 import android.os.SystemClock;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
 
 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;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.function.Supplier;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * BatteryStatsHistory encapsulates battery history files.
@@ -56,57 +66,62 @@
  * All interfaces in BatteryStatsHistory should only be called by BatteryStatsImpl and protected by
  * locks on BatteryStatsImpl object.
  */
-@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
 public class BatteryStatsHistory {
     private static final boolean DEBUG = false;
     private static final String TAG = "BatteryStatsHistory";
 
     // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
-    public static final int VERSION = 208;
+    private static final int VERSION = 208;
 
-    public static final String HISTORY_DIR = "battery-history";
-    public static final String FILE_SUFFIX = ".bin";
+    private static final String HISTORY_DIR = "battery-history";
+    private static final String FILE_SUFFIX = ".bin";
     private static final int MIN_FREE_SPACE = 100 * 1024 * 1024;
+
     // Part of initial delta int that specifies the time delta.
-    public static final int DELTA_TIME_MASK = 0x7ffff;
-    public static final int DELTA_TIME_LONG = 0x7ffff;   // The delta is a following long
-    public static final int DELTA_TIME_INT = 0x7fffe;    // The delta is a following int
-    public static final int DELTA_TIME_ABS = 0x7fffd;    // Following is an entire abs update.
+    static final int DELTA_TIME_MASK = 0x7ffff;
+    static final int DELTA_TIME_LONG = 0x7ffff;   // The delta is a following long
+    static final int DELTA_TIME_INT = 0x7fffe;    // The delta is a following int
+    static final int DELTA_TIME_ABS = 0x7fffd;    // Following is an entire abs update.
     // Flag in delta int: a new battery level int follows.
-    public static final int DELTA_BATTERY_LEVEL_FLAG  = 0x00080000;
+    static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
     // Flag in delta int: a new full state and battery status int follows.
-    public static final int DELTA_STATE_FLAG          = 0x00100000;
+    static final int DELTA_STATE_FLAG = 0x00100000;
     // Flag in delta int: a new full state2 int follows.
-    public static final int DELTA_STATE2_FLAG         = 0x00200000;
+    static final int DELTA_STATE2_FLAG = 0x00200000;
     // Flag in delta int: contains a wakelock or wakeReason tag.
-    public static final int DELTA_WAKELOCK_FLAG       = 0x00400000;
+    static final int DELTA_WAKELOCK_FLAG = 0x00400000;
     // Flag in delta int: contains an event description.
-    public static final int DELTA_EVENT_FLAG          = 0x00800000;
+    static final int DELTA_EVENT_FLAG = 0x00800000;
     // Flag in delta int: contains the battery charge count in uAh.
-    public static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
+    static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
     // These upper bits are the frequently changing state bits.
-    public static final int DELTA_STATE_MASK          = 0xfe000000;
+    static final int DELTA_STATE_MASK = 0xfe000000;
     // These are the pieces of battery state that are packed in to the upper bits of
     // the state int that have been packed in to the first delta int.  They must fit
     // in STATE_BATTERY_MASK.
-    public static final int STATE_BATTERY_MASK         = 0xff000000;
-    public static final int STATE_BATTERY_STATUS_MASK  = 0x00000007;
-    public static final int STATE_BATTERY_STATUS_SHIFT = 29;
-    public static final int STATE_BATTERY_HEALTH_MASK  = 0x00000007;
-    public static final int STATE_BATTERY_HEALTH_SHIFT = 26;
-    public static final int STATE_BATTERY_PLUG_MASK    = 0x00000003;
-    public static final int STATE_BATTERY_PLUG_SHIFT   = 24;
+    static final int STATE_BATTERY_MASK = 0xff000000;
+    static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
+    static final int STATE_BATTERY_STATUS_SHIFT = 29;
+    static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
+    static final int STATE_BATTERY_HEALTH_SHIFT = 26;
+    static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
+    static final int STATE_BATTERY_PLUG_SHIFT = 24;
     // We use the low bit of the battery state int to indicate that we have full details
     // from a battery level change.
-    public static final int BATTERY_DELTA_LEVEL_FLAG   = 0x00000001;
+    static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
     // Flag in history tag index: indicates that this is the first occurrence of this tag,
     // therefore the tag value is written in the parcel
-    public static final int TAG_FIRST_OCCURRENCE_FLAG = 0x8000;
+    static final int TAG_FIRST_OCCURRENCE_FLAG = 0x8000;
 
-    @Nullable
-    private final Supplier<Integer> mMaxHistoryFiles;
     private final Parcel mHistoryBuffer;
+    private final File mSystemDir;
+    private final HistoryStepDetailsCalculator mStepDetailsCalculator;
     private final File mHistoryDir;
+    private final Clock mClock;
+
+    private int mMaxHistoryFiles;
+    private int mMaxHistoryBufferSize;
+
     /**
      * The active history file that the history buffer is backed up into.
      */
@@ -144,19 +159,77 @@
      */
     private int mParcelIndex = 0;
 
+    private final ReentrantLock mWriteLock = new ReentrantLock();
+
+    private final HistoryItem mHistoryCur = new HistoryItem();
+
+    private boolean mHaveBatteryLevel;
+    private boolean mRecordingHistory;
+
+    private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe;
+    private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024;
+
+    private final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
+    private SparseArray<HistoryTag> mHistoryTags;
+    private final HistoryItem mHistoryLastWritten = new HistoryItem();
+    private final HistoryItem mHistoryLastLastWritten = new HistoryItem();
+    private final HistoryItem mHistoryAddTmp = new HistoryItem();
+    private int mNextHistoryTagIdx = 0;
+    private int mNumHistoryTagChars = 0;
+    private int mHistoryBufferLastPos = -1;
+    private int mActiveHistoryStates = 0xffffffff;
+    private int mActiveHistoryStates2 = 0xffffffff;
+    private long mLastHistoryElapsedRealtimeMs = 0;
+    private long mTrackRunningHistoryElapsedRealtimeMs = 0;
+    private long mTrackRunningHistoryUptimeMs = 0;
+    private long mHistoryBaseTimeMs;
+
+    private byte mLastHistoryStepLevel = 0;
+
+    private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator;
+
+    /**
+     * A delegate responsible for computing additional details for a step in battery history.
+     */
+    public interface HistoryStepDetailsCalculator {
+        /**
+         * Returns additional details for the current history step or null.
+         */
+        @Nullable
+        HistoryStepDetails getHistoryStepDetails();
+
+        /**
+         * Resets the calculator to get ready for a new battery session
+         */
+        void clear();
+    }
+
     /**
      * Constructor
      *
-     * @param historyBuffer   The in-memory history buffer.
-     * @param systemDir       typically /data/system
-     * @param maxHistoryFiles the largest number of history buffer files to keep
+     * @param systemDir            typically /data/system
+     * @param maxHistoryFiles      the largest number of history buffer files to keep
+     * @param maxHistoryBufferSize the most amount of RAM to used for buffering of history steps
      */
-    public BatteryStatsHistory(Parcel historyBuffer, File systemDir,
-            Supplier<Integer> maxHistoryFiles) {
-        mHistoryBuffer = historyBuffer;
-        mHistoryDir = new File(systemDir, HISTORY_DIR);
-        mMaxHistoryFiles = maxHistoryFiles;
+    public BatteryStatsHistory(File systemDir, int maxHistoryFiles, int maxHistoryBufferSize,
+            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
+        this(Parcel.obtain(), systemDir, maxHistoryFiles, maxHistoryBufferSize,
+                stepDetailsCalculator, clock);
+        initHistoryBuffer();
+    }
 
+    @VisibleForTesting
+    public BatteryStatsHistory(Parcel historyBuffer, File systemDir,
+            int maxHistoryFiles, int maxHistoryBufferSize,
+            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
+        mHistoryBuffer = historyBuffer;
+        mSystemDir = systemDir;
+        mMaxHistoryFiles = maxHistoryFiles;
+        mMaxHistoryBufferSize = maxHistoryBufferSize;
+        mStepDetailsCalculator = stepDetailsCalculator;
+        mClock = clock;
+
+        mHistoryDir = new File(systemDir, HISTORY_DIR);
         mHistoryDir.mkdirs();
         if (!mHistoryDir.exists()) {
             Slog.wtf(TAG, "HistoryDir does not exist:" + mHistoryDir.getPath());
@@ -192,19 +265,81 @@
         }
     }
 
-    /**
-     * Used when BatteryStatsImpl object is created from deserialization of a parcel,
-     * such as Settings app or checkin file.
-     * @param historyBuffer the history buffer
-     */
-    public BatteryStatsHistory(Parcel historyBuffer) {
+    public BatteryStatsHistory(HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
+        mStepDetailsCalculator = stepDetailsCalculator;
+        mClock = clock;
+
+        mHistoryBuffer = Parcel.obtain();
+        mSystemDir = null;
         mHistoryDir = null;
-        mHistoryBuffer = historyBuffer;
-        mMaxHistoryFiles = null;
+        initHistoryBuffer();
     }
 
-    public File getHistoryDirectory() {
-        return mHistoryDir;
+    /**
+     * Used when BatteryStatsImpl object is created from deserialization of a parcel,
+     * such as a checkin file.
+     */
+    private BatteryStatsHistory(Parcel historyBuffer,
+            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
+        mHistoryBuffer = historyBuffer;
+        mClock = clock;
+        mSystemDir = null;
+        mHistoryDir = null;
+        mStepDetailsCalculator = stepDetailsCalculator;
+    }
+
+    private void initHistoryBuffer() {
+        mHistoryBaseTimeMs = 0;
+        mLastHistoryElapsedRealtimeMs = 0;
+        mTrackRunningHistoryElapsedRealtimeMs = 0;
+        mTrackRunningHistoryUptimeMs = 0;
+
+        mHistoryBuffer.setDataSize(0);
+        mHistoryBuffer.setDataPosition(0);
+        mHistoryBuffer.setDataCapacity(mMaxHistoryBufferSize / 2);
+        mHistoryLastLastWritten.clear();
+        mHistoryLastWritten.clear();
+        mHistoryTagPool.clear();
+        mNextHistoryTagIdx = 0;
+        mNumHistoryTagChars = 0;
+        mHistoryBufferLastPos = -1;
+        mActiveHistoryStates = 0xffffffff;
+        mActiveHistoryStates2 = 0xffffffff;
+        if (mStepDetailsCalculator != null) {
+            mStepDetailsCalculator.clear();
+        }
+    }
+
+    /**
+     * Changes the maximum number of history files to be kept.
+     */
+    public void setMaxHistoryFiles(int maxHistoryFiles) {
+        mMaxHistoryFiles = maxHistoryFiles;
+    }
+
+    /**
+     * Changes the maximum size of the history buffer, in bytes.
+     */
+    public void setMaxHistoryBufferSize(int maxHistoryBufferSize) {
+        mMaxHistoryBufferSize = maxHistoryBufferSize;
+    }
+
+    /**
+     * Creates a read-only copy of the battery history.  Does not copy the files stored
+     * 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);
+    }
+
+    /**
+     * Returns true if this instance only supports reading history.
+     */
+    public boolean isReadOnly() {
+        return mActiveFile == null;
     }
 
     /**
@@ -221,12 +356,13 @@
 
     /**
      * Create history AtomicFile from file number.
+     *
      * @param num file number.
      * @return AtomicFile object.
      */
     private AtomicFile getFile(int num) {
         return new AtomicFile(
-                new File(mHistoryDir,  num + FILE_SUFFIX));
+                new File(mHistoryDir, num + FILE_SUFFIX));
     }
 
     /**
@@ -234,7 +370,7 @@
      * create next history file.
      */
     public void startNextFile() {
-        if (mMaxHistoryFiles == null) {
+        if (mMaxHistoryFiles == 0) {
             Slog.wtf(TAG, "mMaxHistoryFiles should not be zero when writing history");
             return;
         }
@@ -264,7 +400,7 @@
         // if there are more history files than allowed, delete oldest history files.
         // mMaxHistoryFiles comes from Constants.MAX_HISTORY_FILES and can be updated by GService
         // config at run time.
-        while (mFileNumbers.size() > mMaxHistoryFiles.get()) {
+        while (mFileNumbers.size() > mMaxHistoryFiles) {
             int oldest = mFileNumbers.get(0);
             getFile(oldest).delete();
             mFileNumbers.remove(0);
@@ -272,36 +408,43 @@
     }
 
     /**
-     * Delete all existing history files. Active history file start from number 0 again.
+     * Clear history buffer and delete all existing history files. Active history file start from
+     * number 0 again.
      */
-    public void resetAllFiles() {
+    public void reset() {
+        if (DEBUG) Slog.i(TAG, "********** CLEARING HISTORY!");
         for (Integer i : mFileNumbers) {
             getFile(i).delete();
         }
         mFileNumbers.clear();
         mFileNumbers.add(0);
         setActiveFile(0);
+
+        initHistoryBuffer();
     }
 
     /**
      * Start iterating history files and history buffer.
+     *
      * @return always return true.
      */
-    public boolean startIteratingHistory() {
+    public BatteryStatsHistoryIterator iterate() {
         mRecordCount = 0;
         mCurrentFileIndex = 0;
         mCurrentParcel = null;
         mCurrentParcelEnd = 0;
         mParcelIndex = 0;
-        return true;
+        mBatteryStatsHistoryIterator = new BatteryStatsHistoryIterator(this);
+        return mBatteryStatsHistoryIterator;
     }
 
     /**
      * Finish iterating history files and history buffer.
      */
-    public void finishIteratingHistory() {
+    void finishIteratingHistory() {
         // setDataPosition so mHistoryBuffer Parcel can be written.
         mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
+        mBatteryStatsHistoryIterator = null;
         if (DEBUG) {
             Slog.d(TAG, "Battery history records iterated: " + mRecordCount);
         }
@@ -311,11 +454,12 @@
      * When iterating history files and history buffer, always start from the lowest numbered
      * history file, when reached the mActiveFile (highest numbered history file), do not read from
      * mActiveFile, read from history buffer instead because the buffer has more updated data.
+     *
      * @param out a history item.
      * @return The parcel that has next record. null if finished all history files and history
-     *         buffer
+     * buffer
      */
-    public Parcel getNextParcel(BatteryStats.HistoryItem out) {
+    public Parcel getNextParcel(HistoryItem out) {
         if (mRecordCount == 0) {
             // reset out if it is the first record.
             out.clear();
@@ -323,8 +467,7 @@
         ++mRecordCount;
 
         // First iterate through all records in current parcel.
-        if (mCurrentParcel != null)
-        {
+        if (mCurrentParcel != null) {
             if (mCurrentParcel.dataPosition() < mCurrentParcelEnd) {
                 // There are more records in current parcel.
                 return mCurrentParcel;
@@ -389,7 +532,8 @@
 
     /**
      * Read history file into a parcel.
-     * @param out the Parcel read into.
+     *
+     * @param out  the Parcel read into.
      * @param file the File to read from.
      * @return true if success, false otherwise.
      */
@@ -402,8 +546,8 @@
                 Slog.d(TAG, "readFileToParcel:" + file.getBaseFile().getPath()
                         + " duration ms:" + (SystemClock.uptimeMillis() - start));
             }
-        } catch(Exception e) {
-            Slog.e(TAG, "Error reading file "+ file.getBaseFile().getPath(), e);
+        } catch (Exception e) {
+            Slog.e(TAG, "Error reading file " + file.getBaseFile().getPath(), e);
             return false;
         }
         out.unmarshall(raw, 0, raw.length);
@@ -413,6 +557,7 @@
 
     /**
      * Skip the header part of history parcel.
+     *
      * @param p history parcel to skip head.
      * @return true if version match, false if not.
      */
@@ -428,18 +573,68 @@
     }
 
     /**
+     * Writes the battery history contents for persistence.
+     */
+    public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
+        out.writeBoolean(inclHistory);
+        if (inclHistory) {
+            writeToParcel(out);
+        }
+
+        out.writeInt(mHistoryTagPool.size());
+        for (Map.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
+            HistoryTag tag = ent.getKey();
+            out.writeInt(ent.getValue());
+            out.writeString(tag.string);
+            out.writeInt(tag.uid);
+        }
+    }
+
+    /**
+     * Reads battery history contents from a persisted parcel.
+     */
+    public void readSummaryFromParcel(Parcel in) {
+        boolean inclHistory = in.readBoolean();
+        if (inclHistory) {
+            readFromParcel(in);
+        }
+
+        mHistoryTagPool.clear();
+        mNextHistoryTagIdx = 0;
+        mNumHistoryTagChars = 0;
+
+        int numTags = in.readInt();
+        for (int i = 0; i < numTags; i++) {
+            int idx = in.readInt();
+            String str = in.readString();
+            int uid = in.readInt();
+            HistoryTag tag = new HistoryTag();
+            tag.string = str;
+            tag.uid = uid;
+            tag.poolIdx = idx;
+            mHistoryTagPool.put(tag, idx);
+            if (idx >= mNextHistoryTagIdx) {
+                mNextHistoryTagIdx = idx + 1;
+            }
+            mNumHistoryTagChars += tag.string.length() + 1;
+        }
+    }
+
+    /**
      * Read all history files and serialize into a big Parcel.
      * Checkin file calls this method.
      *
      * @param out the output parcel
      */
     public void writeToParcel(Parcel out) {
+        writeHistoryBuffer(out);
         writeToParcel(out, false /* useBlobs */);
     }
 
     /**
      * This is for Settings app, when Settings app receives big history parcel, it call
      * this method to parse it into list of parcels.
+     *
      * @param out the output parcel
      */
     public void writeToBatteryUsageStatsParcel(Parcel out) {
@@ -450,13 +645,13 @@
     private void writeToParcel(Parcel out, boolean useBlobs) {
         final long start = SystemClock.uptimeMillis();
         out.writeInt(mFileNumbers.size() - 1);
-        for(int i = 0;  i < mFileNumbers.size() - 1; i++) {
+        for (int i = 0; i < mFileNumbers.size() - 1; i++) {
             AtomicFile file = getFile(mFileNumbers.get(i));
             byte[] raw = new byte[0];
             try {
                 raw = file.readFully();
-            } catch(Exception e) {
-                Slog.e(TAG, "Error reading file "+ file.getBaseFile().getPath(), e);
+            } catch (Exception e) {
+                Slog.e(TAG, "Error reading file " + file.getBaseFile().getPath(), e);
             }
             if (useBlobs) {
                 out.writeBlob(raw);
@@ -480,17 +675,55 @@
         Parcel historyBuffer = Parcel.obtain();
         historyBuffer.unmarshall(historyBlob, 0, historyBlob.length);
 
-        BatteryStatsHistory history = new BatteryStatsHistory(historyBuffer);
+        BatteryStatsHistory history = new BatteryStatsHistory(historyBuffer, null,
+                Clock.SYSTEM_CLOCK);
         history.readFromParcel(in, true /* useBlobs */);
         return history;
     }
 
     /**
+     * Read history from a check-in file.
+     */
+    public boolean readSummary() {
+        if (mActiveFile == null) {
+            Slog.w(TAG, "readSummary: no history file associated with this instance");
+            return false;
+        }
+
+        Parcel parcel = Parcel.obtain();
+        try {
+            final long start = SystemClock.uptimeMillis();
+            if (mActiveFile.exists()) {
+                byte[] raw = mActiveFile.readFully();
+                if (raw.length > 0) {
+                    parcel.unmarshall(raw, 0, raw.length);
+                    parcel.setDataPosition(0);
+                    readHistoryBuffer(parcel);
+                }
+                if (DEBUG) {
+                    Slog.d(TAG, "read history file::"
+                            + mActiveFile.getBaseFile().getPath()
+                            + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis()
+                            - start));
+                }
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Error reading battery history", e);
+            reset();
+            return false;
+        } finally {
+            parcel.recycle();
+        }
+        return true;
+    }
+
+    /**
      * This is for the check-in file, which has all history files embedded.
      *
      * @param in the input parcel.
      */
     public void readFromParcel(Parcel in) {
+        readHistoryBuffer(in);
         readFromParcel(in, false /* useBlobs */);
     }
 
@@ -498,7 +731,7 @@
         final long start = SystemClock.uptimeMillis();
         mHistoryParcels = new ArrayList<>();
         final int count = in.readInt();
-        for(int i = 0; i < count; i++) {
+        for (int i = 0; i < count; i++) {
             byte[] temp = useBlobs ? in.readBlob() : in.createByteArray();
             if (temp == null || temp.length == 0) {
                 continue;
@@ -521,10 +754,12 @@
         return stats.getAvailableBytes() > MIN_FREE_SPACE;
     }
 
+    @VisibleForTesting
     public List<Integer> getFilesNumbers() {
         return mFileNumbers;
     }
 
+    @VisibleForTesting
     public AtomicFile getActiveFile() {
         return mActiveFile;
     }
@@ -534,15 +769,972 @@
      */
     public int getHistoryUsedSize() {
         int ret = 0;
-        for(int i = 0; i < mFileNumbers.size() - 1; i++) {
+        for (int i = 0; i < mFileNumbers.size() - 1; i++) {
             ret += getFile(mFileNumbers.get(i)).getBaseFile().length();
         }
         ret += mHistoryBuffer.dataSize();
         if (mHistoryParcels != null) {
-            for(int i = 0; i < mHistoryParcels.size(); i++) {
+            for (int i = 0; i < mHistoryParcels.size(); i++) {
                 ret += mHistoryParcels.get(i).dataSize();
             }
         }
         return ret;
     }
+
+    /**
+     * Enables/disables recording of history.  When disabled, all "record*" calls are a no-op.
+     */
+    public void setHistoryRecordingEnabled(boolean enabled) {
+        mRecordingHistory = enabled;
+    }
+
+    /**
+     * Returns true if history recording is enabled.
+     */
+    public boolean isRecordingHistory() {
+        return mRecordingHistory;
+    }
+
+    /**
+     * Forces history recording regardless of charging state.
+     */
+    @VisibleForTesting
+    public void forceRecordAllHistory() {
+        mHaveBatteryLevel = true;
+        mRecordingHistory = true;
+    }
+
+    /**
+     * Starts a history buffer by recording the current wall-clock time.
+     */
+    public void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
+            boolean reset) {
+        mRecordingHistory = true;
+        mHistoryCur.currentTime = mClock.currentTimeMillis();
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, mHistoryCur,
+                reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME);
+        mHistoryCur.currentTime = 0;
+    }
+
+    /**
+     * Prepares to continue recording after restoring previous history from persistent storage.
+     */
+    public void continueRecordingHistory() {
+        if (mHistoryBuffer.dataPosition() <= 0 && mFileNumbers.size() <= 1) {
+            return;
+        }
+
+        mRecordingHistory = true;
+        final long elapsedRealtimeMs = mClock.elapsedRealtime();
+        final long uptimeMs = mClock.uptimeMillis();
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, mHistoryCur, HistoryItem.CMD_START);
+        startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
+    }
+
+    /**
+     * Notes the current battery state to be reflected in the next written history item.
+     */
+    public void setBatteryState(boolean charging, int status, int level, int chargeUah) {
+        mHaveBatteryLevel = true;
+        setChargingState(charging);
+        mHistoryCur.batteryStatus = (byte) status;
+        mHistoryCur.batteryLevel = (byte) level;
+        mHistoryCur.batteryChargeUah = chargeUah;
+    }
+
+    /**
+     * Notes the current battery state to be reflected in the next written history item.
+     */
+    public void setBatteryState(int status, int level, int health, int plugType, int temperature,
+            int voltageMv, int chargeUah) {
+        mHaveBatteryLevel = true;
+        mHistoryCur.batteryStatus = (byte) status;
+        mHistoryCur.batteryLevel = (byte) level;
+        mHistoryCur.batteryHealth = (byte) health;
+        mHistoryCur.batteryPlugType = (byte) plugType;
+        mHistoryCur.batteryTemperature = (short) temperature;
+        mHistoryCur.batteryVoltage = (char) voltageMv;
+        mHistoryCur.batteryChargeUah = chargeUah;
+    }
+
+    /**
+     * Notes the current power plugged-in state to be reflected in the next written history item.
+     */
+    public void setPluggedInState(boolean pluggedIn) {
+        if (pluggedIn) {
+            mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+        } else {
+            mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+        }
+    }
+
+    /**
+     * Notes the current battery charging state to be reflected in the next written history item.
+     */
+    public void setChargingState(boolean charging) {
+        if (charging) {
+            mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
+        } else {
+            mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
+        }
+    }
+
+    /**
+     * Records a history event with the given code, name and UID.
+     */
+    public void recordEvent(long elapsedRealtimeMs, long uptimeMs, int code, String name,
+            int uid) {
+        mHistoryCur.eventCode = code;
+        mHistoryCur.eventTag = mHistoryCur.localEventTag;
+        mHistoryCur.eventTag.string = name;
+        mHistoryCur.eventTag.uid = uid;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a time change event.
+     */
+    public void recordCurrentTimeChange(long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) {
+        if (!mRecordingHistory) {
+            return;
+        }
+
+        mHistoryCur.currentTime = currentTimeMs;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, mHistoryCur,
+                HistoryItem.CMD_CURRENT_TIME);
+        mHistoryCur.currentTime = 0;
+    }
+
+    /**
+     * Records a system shutdown event.
+     */
+    public void recordShutdownEvent(long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) {
+        if (!mRecordingHistory) {
+            return;
+        }
+
+        mHistoryCur.currentTime = currentTimeMs;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, mHistoryCur, HistoryItem.CMD_SHUTDOWN);
+        mHistoryCur.currentTime = 0;
+    }
+
+    /**
+     * Records a battery state change event.
+     */
+    public void recordBatteryState(long elapsedRealtimeMs, long uptimeMs, int batteryLevel,
+            boolean isPlugged) {
+        mHistoryCur.batteryLevel = (byte) batteryLevel;
+        setPluggedInState(isPlugged);
+        if (DEBUG) {
+            Slog.v(TAG, "Battery unplugged to: "
+                    + Integer.toHexString(mHistoryCur.states));
+        }
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a history item with the amount of charge consumed by WiFi.  Used on certain devices
+     * equipped with on-device power metering.
+     */
+    public void recordWifiConsumedCharge(long elapsedRealtimeMs, long uptimeMs,
+            double monitoredRailChargeMah) {
+        mHistoryCur.wifiRailChargeMah += monitoredRailChargeMah;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a wakelock start event.
+     */
+    public void recordWakelockStartEvent(long elapsedRealtimeMs, long uptimeMs, String historyName,
+            int uid) {
+        mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
+        mHistoryCur.wakelockTag.string = historyName;
+        mHistoryCur.wakelockTag.uid = uid;
+        recordStateStartEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.STATE_WAKE_LOCK_FLAG);
+    }
+
+    /**
+     * Updates the previous history event with a wakelock name and UID.
+     */
+    public boolean maybeUpdateWakelockTag(long elapsedRealtimeMs, long uptimeMs, String historyName,
+            int uid) {
+        if (mHistoryLastWritten.cmd != HistoryItem.CMD_UPDATE) {
+            return false;
+        }
+        if (mHistoryLastWritten.wakelockTag != null) {
+            // We'll try to update the last tag.
+            mHistoryLastWritten.wakelockTag = null;
+            mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
+            mHistoryCur.wakelockTag.string = historyName;
+            mHistoryCur.wakelockTag.uid = uid;
+            writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+        }
+        return true;
+    }
+
+    /**
+     * Records an event when some state flag changes to true.
+     */
+    public void recordStateStartEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
+        mHistoryCur.states |= stateFlags;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records an event when some state flag changes to false.
+     */
+    public void recordStateStopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
+        mHistoryCur.states &= ~stateFlags;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records an event when some state flags change to true and some to false.
+     */
+    public void recordStateChangeEvent(long elapsedRealtimeMs, long uptimeMs, int stateStartFlags,
+            int stateStopFlags) {
+        mHistoryCur.states = (mHistoryCur.states | stateStartFlags) & ~stateStopFlags;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records an event when some state2 flag changes to true.
+     */
+    public void recordState2StartEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
+        mHistoryCur.states2 |= stateFlags;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records an event when some state2 flag changes to false.
+     */
+    public void recordState2StopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
+        mHistoryCur.states2 &= ~stateFlags;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records an wakeup event.
+     */
+    public void recordWakeupEvent(long elapsedRealtimeMs, long uptimeMs, String reason) {
+        mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
+        mHistoryCur.wakeReasonTag.string = reason;
+        mHistoryCur.wakeReasonTag.uid = 0;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a screen brightness change event.
+     */
+    public void recordScreenBrightnessEvent(long elapsedRealtimeMs, long uptimeMs,
+            int brightnessBin) {
+        mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK)
+                | (brightnessBin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a GNSS signal level change event.
+     */
+    public void recordGpsSignalQualityEvent(long elapsedRealtimeMs, long uptimeMs,
+            int signalLevel) {
+        mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
+                | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a device idle mode change event.
+     */
+    public void recordDeviceIdleEvent(long elapsedRealtimeMs, long uptimeMs, int mode) {
+        mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
+                | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a telephony state change event.
+     */
+    public void recordPhoneStateChangeEvent(long elapsedRealtimeMs, long uptimeMs, int addStateFlag,
+            int removeStateFlag, int state, int signalStrength) {
+        mHistoryCur.states = (mHistoryCur.states | addStateFlag) & ~removeStateFlag;
+        if (state != -1) {
+            mHistoryCur.states =
+                    (mHistoryCur.states & ~HistoryItem.STATE_PHONE_STATE_MASK)
+                            | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
+        }
+        if (signalStrength != -1) {
+            mHistoryCur.states =
+                    (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
+                            | (signalStrength << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
+        }
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a data connection type change event.
+     */
+    public void recordDataConnectionTypeChangeEvent(long elapsedRealtimeMs, long uptimeMs,
+            int dataConnectionType) {
+        mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_DATA_CONNECTION_MASK)
+                | (dataConnectionType << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a WiFi supplicant state change event.
+     */
+    public void recordWifiSupplicantStateChangeEvent(long elapsedRealtimeMs, long uptimeMs,
+            int supplState) {
+        mHistoryCur.states2 =
+                (mHistoryCur.states2 & ~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
+                        | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Records a WiFi signal strength change event.
+     */
+    public void recordWifiSignalStrengthChangeEvent(long elapsedRealtimeMs, long uptimeMs,
+            int strengthBin) {
+        mHistoryCur.states2 =
+                (mHistoryCur.states2 & ~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
+                        | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+    }
+
+    /**
+     * Writes the current history item to history.
+     */
+    public void writeHistoryItem(long elapsedRealtimeMs, long uptimeMs) {
+        if (mTrackRunningHistoryElapsedRealtimeMs != 0) {
+            final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs;
+            final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs;
+            if (diffUptimeMs < (diffElapsedMs - 20)) {
+                final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs);
+                mHistoryAddTmp.setTo(mHistoryLastWritten);
+                mHistoryAddTmp.wakelockTag = null;
+                mHistoryAddTmp.wakeReasonTag = null;
+                mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
+                mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
+                writeHistoryItem(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp);
+            }
+        }
+        mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
+        mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs;
+        mTrackRunningHistoryUptimeMs = uptimeMs;
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, mHistoryCur);
+    }
+
+    private void writeHistoryItem(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
+        if (!mHaveBatteryLevel || !mRecordingHistory) {
+            return;
+        }
+
+        final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time;
+        final int diffStates = mHistoryLastWritten.states ^ (cur.states & mActiveHistoryStates);
+        final int diffStates2 = mHistoryLastWritten.states2 ^ (cur.states2 & mActiveHistoryStates2);
+        final int lastDiffStates = mHistoryLastWritten.states ^ mHistoryLastLastWritten.states;
+        final int lastDiffStates2 = mHistoryLastWritten.states2 ^ mHistoryLastLastWritten.states2;
+        if (DEBUG) {
+            Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff="
+                    + Integer.toHexString(diffStates) + " lastDiff="
+                    + Integer.toHexString(lastDiffStates) + " diff2="
+                    + Integer.toHexString(diffStates2) + " lastDiff2="
+                    + Integer.toHexString(lastDiffStates2));
+        }
+        if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
+                && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0
+                && (diffStates2 & lastDiffStates2) == 0
+                && (!mHistoryLastWritten.tagsFirstOccurrence && !cur.tagsFirstOccurrence)
+                && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
+                && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
+                && mHistoryLastWritten.stepDetails == null
+                && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
+                || cur.eventCode == HistoryItem.EVENT_NONE)
+                && mHistoryLastWritten.batteryLevel == cur.batteryLevel
+                && mHistoryLastWritten.batteryStatus == cur.batteryStatus
+                && mHistoryLastWritten.batteryHealth == cur.batteryHealth
+                && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
+                && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
+                && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
+            // We can merge this new change in with the last one.  Merging is
+            // allowed as long as only the states have changed, and within those states
+            // 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);
+            mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
+            mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
+            mHistoryBufferLastPos = -1;
+            elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs;
+            // If the last written history had a wakelock tag, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have a wakelock tag.
+            if (mHistoryLastWritten.wakelockTag != null) {
+                cur.wakelockTag = cur.localWakelockTag;
+                cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
+            }
+            // If the last written history had a wake reason tag, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have a wakelock tag.
+            if (mHistoryLastWritten.wakeReasonTag != null) {
+                cur.wakeReasonTag = cur.localWakeReasonTag;
+                cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
+            }
+            // If the last written history had an event, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have an event.
+            if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
+                cur.eventCode = mHistoryLastWritten.eventCode;
+                cur.eventTag = cur.localEventTag;
+                cur.eventTag.setTo(mHistoryLastWritten.eventTag);
+            }
+            mHistoryLastWritten.setTo(mHistoryLastLastWritten);
+        }
+        final int dataSize = mHistoryBuffer.dataSize();
+
+        if (dataSize >= mMaxHistoryBufferSize) {
+            if (mMaxHistoryBufferSize == 0) {
+                Slog.wtf(TAG, "mMaxHistoryBufferSize should not be zero when writing history");
+                mMaxHistoryBufferSize = 1024;
+            }
+
+            //open a new history file.
+            final long start = SystemClock.uptimeMillis();
+            writeHistory();
+            if (DEBUG) {
+                Slog.d(TAG, "addHistoryBufferLocked writeHistory took ms:"
+                        + (SystemClock.uptimeMillis() - start));
+            }
+            startNextFile();
+            mHistoryBuffer.setDataSize(0);
+            mHistoryBuffer.setDataPosition(0);
+            mHistoryBuffer.setDataCapacity(mMaxHistoryBufferSize / 2);
+            mHistoryBufferLastPos = -1;
+            mHistoryLastWritten.clear();
+            mHistoryLastLastWritten.clear();
+
+            // Mark every entry in the pool with a flag indicating that the tag
+            // has not yet been encountered while writing the current history buffer.
+            for (Map.Entry<HistoryTag, Integer> entry : mHistoryTagPool.entrySet()) {
+                entry.setValue(entry.getValue() | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG);
+            }
+            // Make a copy of mHistoryCur.
+            HistoryItem copy = new HistoryItem();
+            copy.setTo(cur);
+            // startRecordingHistory will reset mHistoryCur.
+            startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
+            // Add the copy into history buffer.
+            writeHistoryItem(elapsedRealtimeMs, uptimeMs, copy, HistoryItem.CMD_UPDATE);
+            return;
+        }
+
+        if (dataSize == 0) {
+            // The history is currently empty; we need it to start with a time stamp.
+            cur.currentTime = mClock.currentTimeMillis();
+            writeHistoryItem(elapsedRealtimeMs, uptimeMs, cur, HistoryItem.CMD_RESET);
+        }
+        writeHistoryItem(elapsedRealtimeMs, uptimeMs, cur, HistoryItem.CMD_UPDATE);
+    }
+
+    private void writeHistoryItem(long elapsedRealtimeMs,
+            @SuppressWarnings("UnusedVariable") long uptimeMs, HistoryItem cur, byte cmd) {
+        if (mBatteryStatsHistoryIterator != null) {
+            throw new IllegalStateException("Can't do this while iterating history!");
+        }
+        mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
+        mHistoryLastLastWritten.setTo(mHistoryLastWritten);
+        final boolean hasTags = mHistoryLastWritten.tagsFirstOccurrence || cur.tagsFirstOccurrence;
+        mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
+        mHistoryLastWritten.tagsFirstOccurrence = hasTags;
+        mHistoryLastWritten.states &= mActiveHistoryStates;
+        mHistoryLastWritten.states2 &= mActiveHistoryStates2;
+        writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
+        mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs;
+        cur.wakelockTag = null;
+        cur.wakeReasonTag = null;
+        cur.eventCode = HistoryItem.EVENT_NONE;
+        cur.eventTag = null;
+        cur.tagsFirstOccurrence = false;
+        if (DEBUG) {
+            Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
+                    + " now " + mHistoryBuffer.dataPosition()
+                    + " size is now " + mHistoryBuffer.dataSize());
+        }
+    }
+
+    /*
+        The history delta format uses flags to denote further data in subsequent ints in the parcel.
+
+        There is always the first token, which may contain the delta time, or an indicator of
+        the length of the time (int or long) following this token.
+
+        First token: always present,
+        31              23              15               7             0
+        █M|L|K|J|I|H|G|F█E|D|C|B|A|T|T|T█T|T|T|T|T|T|T|T█T|T|T|T|T|T|T|T█
+
+        T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
+           follows containing the time, and 0x7ffff indicates a long immediately follows with the
+           delta time.
+        A: battery level changed and an int follows with battery data.
+        B: state changed and an int follows with state change data.
+        C: state2 has changed and an int follows with state2 change data.
+        D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
+        E: event data has changed and an event struct follows.
+        F: battery charge in coulombs has changed and an int with the charge follows.
+        G: state flag denoting that the mobile radio was active.
+        H: state flag denoting that the wifi radio was active.
+        I: state flag denoting that a wifi scan occurred.
+        J: state flag denoting that a wifi full lock was held.
+        K: state flag denoting that the gps was on.
+        L: state flag denoting that a wakelock was held.
+        M: state flag denoting that the cpu was running.
+
+        Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
+        with the time delta.
+
+        Battery level int: if A in the first token is set,
+        31              23              15               7             0
+        █L|L|L|L|L|L|L|T█T|T|T|T|T|T|T|T█T|V|V|V|V|V|V|V█V|V|V|V|V|V|V|D█
+
+        D: indicates that extra history details follow.
+        V: the battery voltage.
+        T: the battery temperature.
+        L: the battery level (out of 100).
+
+        State change int: if B in the first token is set,
+        31              23              15               7             0
+        █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █
+
+        A: wifi multicast was on.
+        B: battery was plugged in.
+        C: screen was on.
+        D: phone was scanning for signal.
+        E: audio was on.
+        F: a sensor was active.
+
+        State2 change int: if C in the first token is set,
+        31              23              15               7             0
+        █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█
+
+        A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
+        B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
+        C: a bluetooth scan was active.
+        D: the camera was active.
+        E: bluetooth was on.
+        F: a phone call was active.
+        G: the device was charging.
+        H: 2 bits indicating the device-idle (doze) state: off, light, full
+        I: the flashlight was on.
+        J: wifi was on.
+        K: wifi was running.
+        L: video was playing.
+        M: power save mode was on.
+
+        Wakelock/wakereason struct: if D in the first token is set,
+        Event struct: if E in the first token is set,
+        History step details struct: if D in the battery level int is set,
+
+        Battery charge int: if F in the first token is set, an int representing the battery charge
+        in coulombs follows.
+     */
+    /**
+     * Writes the delta between the previous and current history items into history buffer.
+     */
+    public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
+        if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
+            dest.writeInt(BatteryStatsHistory.DELTA_TIME_ABS);
+            cur.writeToParcel(dest, 0);
+            return;
+        }
+
+        final long deltaTime = cur.time - last.time;
+        final int lastBatteryLevelInt = buildBatteryLevelInt(last);
+        final int lastStateInt = buildStateInt(last);
+
+        int deltaTimeToken;
+        if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
+            deltaTimeToken = BatteryStatsHistory.DELTA_TIME_LONG;
+        } else if (deltaTime >= BatteryStatsHistory.DELTA_TIME_ABS) {
+            deltaTimeToken = BatteryStatsHistory.DELTA_TIME_INT;
+        } else {
+            deltaTimeToken = (int) deltaTime;
+        }
+        int firstToken = deltaTimeToken | (cur.states & BatteryStatsHistory.DELTA_STATE_MASK);
+        final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
+                ? BatteryStatsHistory.BATTERY_DELTA_LEVEL_FLAG : 0;
+        mLastHistoryStepLevel = cur.batteryLevel;
+        final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
+        final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
+        if (batteryLevelIntChanged) {
+            firstToken |= BatteryStatsHistory.DELTA_BATTERY_LEVEL_FLAG;
+        }
+        final int stateInt = buildStateInt(cur);
+        final boolean stateIntChanged = stateInt != lastStateInt;
+        if (stateIntChanged) {
+            firstToken |= BatteryStatsHistory.DELTA_STATE_FLAG;
+        }
+        final boolean state2IntChanged = cur.states2 != last.states2;
+        if (state2IntChanged) {
+            firstToken |= BatteryStatsHistory.DELTA_STATE2_FLAG;
+        }
+        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
+            firstToken |= BatteryStatsHistory.DELTA_WAKELOCK_FLAG;
+        }
+        if (cur.eventCode != HistoryItem.EVENT_NONE) {
+            firstToken |= BatteryStatsHistory.DELTA_EVENT_FLAG;
+        }
+
+        final boolean batteryChargeChanged = cur.batteryChargeUah != last.batteryChargeUah;
+        if (batteryChargeChanged) {
+            firstToken |= BatteryStatsHistory.DELTA_BATTERY_CHARGE_FLAG;
+        }
+        dest.writeInt(firstToken);
+        if (DEBUG) {
+            Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
+                    + " deltaTime=" + deltaTime);
+        }
+
+        if (deltaTimeToken >= BatteryStatsHistory.DELTA_TIME_INT) {
+            if (deltaTimeToken == BatteryStatsHistory.DELTA_TIME_INT) {
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int) deltaTime);
+                dest.writeInt((int) deltaTime);
+            } else {
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
+                dest.writeLong(deltaTime);
+            }
+        }
+        if (batteryLevelIntChanged) {
+            dest.writeInt(batteryLevelInt);
+            if (DEBUG) {
+                Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
+                        + Integer.toHexString(batteryLevelInt)
+                        + " batteryLevel=" + cur.batteryLevel
+                        + " batteryTemp=" + cur.batteryTemperature
+                        + " batteryVolt=" + (int) cur.batteryVoltage);
+            }
+        }
+        if (stateIntChanged) {
+            dest.writeInt(stateInt);
+            if (DEBUG) {
+                Slog.i(TAG, "WRITE DELTA: stateToken=0x"
+                        + Integer.toHexString(stateInt)
+                        + " batteryStatus=" + cur.batteryStatus
+                        + " batteryHealth=" + cur.batteryHealth
+                        + " batteryPlugType=" + cur.batteryPlugType
+                        + " states=0x" + Integer.toHexString(cur.states));
+            }
+        }
+        if (state2IntChanged) {
+            dest.writeInt(cur.states2);
+            if (DEBUG) {
+                Slog.i(TAG, "WRITE DELTA: states2=0x"
+                        + Integer.toHexString(cur.states2));
+            }
+        }
+        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
+            int wakeLockIndex;
+            int wakeReasonIndex;
+            if (cur.wakelockTag != null) {
+                wakeLockIndex = writeHistoryTag(cur.wakelockTag);
+                if (DEBUG) {
+                    Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
+                            + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
+                }
+            } else {
+                wakeLockIndex = 0xffff;
+            }
+            if (cur.wakeReasonTag != null) {
+                wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
+                if (DEBUG) {
+                    Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
+                            + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
+                }
+            } else {
+                wakeReasonIndex = 0xffff;
+            }
+            dest.writeInt((wakeReasonIndex << 16) | wakeLockIndex);
+            if (cur.wakelockTag != null
+                    && (wakeLockIndex & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
+                cur.wakelockTag.writeToParcel(dest, 0);
+                cur.tagsFirstOccurrence = true;
+            }
+            if (cur.wakeReasonTag != null
+                    && (wakeReasonIndex & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
+                cur.wakeReasonTag.writeToParcel(dest, 0);
+                cur.tagsFirstOccurrence = true;
+            }
+        }
+        if (cur.eventCode != HistoryItem.EVENT_NONE) {
+            final int index = writeHistoryTag(cur.eventTag);
+            final int codeAndIndex = (cur.eventCode & 0xffff) | (index << 16);
+            dest.writeInt(codeAndIndex);
+            if ((index & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
+                cur.eventTag.writeToParcel(dest, 0);
+                cur.tagsFirstOccurrence = true;
+            }
+            if (DEBUG) {
+                Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
+                        + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
+                        + cur.eventTag.string);
+            }
+        }
+
+        cur.stepDetails = mStepDetailsCalculator.getHistoryStepDetails();
+        if (includeStepDetails != 0) {
+            cur.stepDetails.writeToParcel(dest);
+        }
+
+        if (batteryChargeChanged) {
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUah=" + cur.batteryChargeUah);
+            dest.writeInt(cur.batteryChargeUah);
+        }
+        dest.writeDouble(cur.modemRailChargeMah);
+        dest.writeDouble(cur.wifiRailChargeMah);
+    }
+
+    private int buildBatteryLevelInt(HistoryItem h) {
+        return ((((int) h.batteryLevel) << 25) & 0xfe000000)
+                | ((((int) h.batteryTemperature) << 15) & 0x01ff8000)
+                | ((((int) h.batteryVoltage) << 1) & 0x00007ffe);
+    }
+
+    private int buildStateInt(HistoryItem h) {
+        int plugType = 0;
+        if ((h.batteryPlugType & BatteryManager.BATTERY_PLUGGED_AC) != 0) {
+            plugType = 1;
+        } else if ((h.batteryPlugType & BatteryManager.BATTERY_PLUGGED_USB) != 0) {
+            plugType = 2;
+        } else if ((h.batteryPlugType & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
+            plugType = 3;
+        }
+        return ((h.batteryStatus & BatteryStatsHistory.STATE_BATTERY_STATUS_MASK)
+                << BatteryStatsHistory.STATE_BATTERY_STATUS_SHIFT)
+                | ((h.batteryHealth & BatteryStatsHistory.STATE_BATTERY_HEALTH_MASK)
+                << BatteryStatsHistory.STATE_BATTERY_HEALTH_SHIFT)
+                | ((plugType & BatteryStatsHistory.STATE_BATTERY_PLUG_MASK)
+                << BatteryStatsHistory.STATE_BATTERY_PLUG_SHIFT)
+                | (h.states & (~BatteryStatsHistory.STATE_BATTERY_MASK));
+    }
+
+    /**
+     * Returns the index for the specified tag. If this is the first time the tag is encountered
+     * while writing the current history buffer, the method returns
+     * <code>(index | TAG_FIRST_OCCURRENCE_FLAG)</code>
+     */
+    private int writeHistoryTag(HistoryTag tag) {
+        if (tag.string == null) {
+            Slog.wtfStack(TAG, "writeHistoryTag called with null name");
+        }
+
+        final int stringLength = tag.string.length();
+        if (stringLength > MAX_HISTORY_TAG_STRING_LENGTH) {
+            Slog.e(TAG, "Long battery history tag: " + tag.string);
+            tag.string = tag.string.substring(0, MAX_HISTORY_TAG_STRING_LENGTH);
+        }
+
+        Integer idxObj = mHistoryTagPool.get(tag);
+        int idx;
+        if (idxObj != null) {
+            idx = idxObj;
+            if ((idx & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
+                mHistoryTagPool.put(tag, idx & ~BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG);
+            }
+            return idx;
+        } else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) {
+            idx = mNextHistoryTagIdx;
+            HistoryTag key = new HistoryTag();
+            key.setTo(tag);
+            tag.poolIdx = idx;
+            mHistoryTagPool.put(key, idx);
+            mNextHistoryTagIdx++;
+
+            mNumHistoryTagChars += stringLength + 1;
+            if (mHistoryTags != null) {
+                mHistoryTags.put(idx, key);
+            }
+            return idx | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG;
+        } else {
+            // Tag pool overflow: include the tag itself in the parcel
+            return HISTORY_TAG_INDEX_LIMIT | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG;
+        }
+    }
+
+    /**
+     * Don't allow any more batching in to the current history event.
+     */
+    public void commitCurrentHistoryBatchLocked() {
+        mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
+    }
+
+    /**
+     * Saves the accumulated history buffer in the active file, see {@link #getActiveFile()} .
+     */
+    public void writeHistory() {
+        if (mActiveFile == null) {
+            Slog.w(TAG, "writeHistory: no history file associated with this instance");
+            return;
+        }
+
+        Parcel p = Parcel.obtain();
+        try {
+            final long start = SystemClock.uptimeMillis();
+            writeHistoryBuffer(p);
+            if (DEBUG) {
+                Slog.d(TAG, "writeHistoryBuffer duration ms:"
+                        + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize());
+            }
+            writeParcelToFileLocked(p, mActiveFile);
+        } finally {
+            p.recycle();
+        }
+    }
+
+    /**
+     * Reads history buffer from a persisted Parcel.
+     */
+    public void readHistoryBuffer(Parcel in) throws ParcelFormatException {
+        final int version = in.readInt();
+        if (version != BatteryStatsHistory.VERSION) {
+            Slog.w("BatteryStats", "readHistoryBuffer: version got " + version
+                    + ", expected " + BatteryStatsHistory.VERSION + "; erasing old stats");
+            return;
+        }
+
+        final long historyBaseTime = in.readLong();
+
+        mHistoryBuffer.setDataSize(0);
+        mHistoryBuffer.setDataPosition(0);
+
+        int bufSize = in.readInt();
+        int curPos = in.dataPosition();
+        if (bufSize >= (mMaxHistoryBufferSize * 100)) {
+            throw new ParcelFormatException(
+                    "File corrupt: history data buffer too large " + bufSize);
+        } else if ((bufSize & ~3) != bufSize) {
+            throw new ParcelFormatException(
+                    "File corrupt: history data buffer not aligned " + bufSize);
+        } else {
+            if (DEBUG) {
+                Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
+                        + " bytes at " + curPos);
+            }
+            mHistoryBuffer.appendFrom(in, curPos, bufSize);
+            in.setDataPosition(curPos + bufSize);
+        }
+
+        if (DEBUG) {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("****************** OLD mHistoryBaseTimeMs: ");
+            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
+            Slog.i(TAG, sb.toString());
+        }
+        mHistoryBaseTimeMs = historyBaseTime;
+        if (DEBUG) {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("****************** NEW mHistoryBaseTimeMs: ");
+            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
+            Slog.i(TAG, sb.toString());
+        }
+
+        // We are just arbitrarily going to insert 1 minute from the sample of
+        // the last run until samples in this run.
+        if (mHistoryBaseTimeMs > 0) {
+            long oldnow = mClock.elapsedRealtime();
+            mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1;
+            if (DEBUG) {
+                StringBuilder sb = new StringBuilder(128);
+                sb.append("****************** ADJUSTED mHistoryBaseTimeMs: ");
+                TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
+                Slog.i(TAG, sb.toString());
+            }
+        }
+    }
+
+    private void writeHistoryBuffer(Parcel out) {
+        if (DEBUG) {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("****************** WRITING mHistoryBaseTimeMs: ");
+            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
+            sb.append(" mLastHistoryElapsedRealtimeMs: ");
+            TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb);
+            Slog.i(TAG, sb.toString());
+        }
+        out.writeInt(BatteryStatsHistory.VERSION);
+        out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs);
+        out.writeInt(mHistoryBuffer.dataSize());
+        if (DEBUG) {
+            Slog.i(TAG, "***************** WRITING HISTORY: "
+                    + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
+        }
+        out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
+    }
+
+    private void writeParcelToFileLocked(Parcel p, AtomicFile file) {
+        FileOutputStream fos = null;
+        mWriteLock.lock();
+        try {
+            final long startTimeMs = SystemClock.uptimeMillis();
+            fos = file.startWrite();
+            fos.write(p.marshall());
+            fos.flush();
+            file.finishWrite(fos);
+            if (DEBUG) {
+                Slog.d(TAG, "writeParcelToFileLocked file:" + file.getBaseFile().getPath()
+                        + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs)
+                        + " bytes:" + p.dataSize());
+            }
+            com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+                    "batterystats", SystemClock.uptimeMillis() - startTimeMs);
+        } catch (IOException e) {
+            Slog.w(TAG, "Error writing battery statistics", e);
+            file.failWrite(fos);
+        } finally {
+            mWriteLock.unlock();
+        }
+    }
+
+    /**
+     * Returns the total number of history tags in the tag pool.
+     */
+    public int getHistoryStringPoolSize() {
+        return mHistoryTagPool.size();
+    }
+
+    /**
+     * Returns the total number of bytes occupied by the history tag pool.
+     */
+    public int getHistoryStringPoolBytes() {
+        return mNumHistoryTagChars;
+    }
+
+    /**
+     * Returns the string held by the requested history tag.
+     */
+    public String getHistoryTagPoolString(int index) {
+        ensureHistoryTagArray();
+        HistoryTag historyTag = mHistoryTags.get(index);
+        return historyTag != null ? historyTag.string : null;
+    }
+
+    /**
+     * Returns the UID held by the requested history tag.
+     */
+    public int getHistoryTagPoolUid(int index) {
+        ensureHistoryTagArray();
+        HistoryTag historyTag = mHistoryTags.get(index);
+        return historyTag != null ? historyTag.uid : Process.INVALID_UID;
+    }
+
+    private void ensureHistoryTagArray() {
+        if (mHistoryTags != null) {
+            return;
+        }
+
+        mHistoryTags = new SparseArray<>(mHistoryTagPool.size());
+        for (Map.Entry<HistoryTag, Integer> entry : mHistoryTagPool.entrySet()) {
+            mHistoryTags.put(entry.getValue() & ~BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG,
+                    entry.getKey());
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
index de8b414..1bf878cb 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
@@ -36,7 +36,6 @@
 
     public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history) {
         mBatteryStatsHistory = history;
-        mBatteryStatsHistory.startIteratingHistory();
     }
 
     /**
@@ -231,4 +230,11 @@
         out.batteryTemperature = (short) ((batteryLevelInt & 0x01ff8000) >>> 15);
         out.batteryVoltage = (char) ((batteryLevelInt & 0x00007ffe) >>> 1);
     }
+
+    /**
+     * Should be called when iteration is complete.
+     */
+    public void close() {
+        mBatteryStatsHistory.finishIteratingHistory();
+    }
 }
diff --git a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
index fe4aa53..df902c2 100644
--- a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
@@ -657,7 +657,7 @@
 
         // Now that we have finally received all the data, we can tell mStats about it.
         synchronized (mStats) {
-            mStats.addHistoryEventLocked(
+            mStats.recordHistoryEventLocked(
                     elapsedRealtime,
                     uptime,
                     BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS,
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 0c9ada8..968f916 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -108,6 +108,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BatteryStatsHistory;
+import com.android.internal.os.BatteryStatsHistory.HistoryStepDetailsCalculator;
 import com.android.internal.os.BatteryStatsHistoryIterator;
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.BinderTransactionNameResolver;
@@ -173,7 +174,6 @@
     private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
     private static final boolean DEBUG_BINDER_STATS = false;
     private static final boolean DEBUG_MEMORY = false;
-    private static final boolean DEBUG_HISTORY = false;
 
     // TODO: remove "tcp" from network methods, since we measure total stats.
 
@@ -322,6 +322,11 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>();
 
+    @NonNull
+    BatteryStatsHistory copyHistory() {
+        return mHistory.copy();
+    }
+
     @VisibleForTesting
     public final class UidToRemove {
         private final int mStartUid;
@@ -413,7 +418,7 @@
                 if (changed) {
                     final long uptimeMs = mClock.uptimeMillis();
                     final long elapsedRealtimeMs = mClock.elapsedRealtime();
-                    addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                    mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs);
                 }
             }
         }
@@ -668,16 +673,16 @@
     /**
      * Mapping isolated uids to the actual owning app uid.
      */
-    final SparseIntArray mIsolatedUids = new SparseIntArray();
+    private final SparseIntArray mIsolatedUids = new SparseIntArray();
     /**
      * Internal reference count of isolated uids.
      */
-    final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
+    private final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
 
     /**
      * The statistics we have collected organized by uids.
      */
-    final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
+    private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
 
     // A set of pools of currently active timers.  When a timer is queried, we will divide the
     // elapsed time by the number of active timers to arrive at that timer's share of the time.
@@ -685,20 +690,21 @@
     // changes.
     @VisibleForTesting
     protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
-    final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
-    final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
-    final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
-    final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
-    final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
+    private final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
+    private final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
+    private final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
+            new SparseArray<>();
+    private final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
+    private final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>();
 
     // Last partial timers we use for distributing CPU usage.
     @VisibleForTesting
@@ -713,69 +719,24 @@
     protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true);
 
     private boolean mSystemReady;
-    boolean mShuttingDown;
+    private boolean mShuttingDown;
 
-    final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
+    private final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
+    private final HistoryStepDetailsCalculatorImpl mStepDetailsCalculator =
+            new HistoryStepDetailsCalculatorImpl();
 
-    long mHistoryBaseTimeMs;
-    protected boolean mHaveBatteryLevel = false;
-    protected boolean mRecordingHistory = false;
-    int mNumHistoryItems;
-
-    private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe;
-    private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024;
-
-    final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
-    private SparseArray<HistoryTag> mHistoryTags;
-    final Parcel mHistoryBuffer = Parcel.obtain();
-    final HistoryItem mHistoryLastWritten = new HistoryItem();
-    final HistoryItem mHistoryLastLastWritten = new HistoryItem();
-    final HistoryItem mHistoryAddTmp = new HistoryItem();
-    int mNextHistoryTagIdx = 0;
-    int mNumHistoryTagChars = 0;
-    int mHistoryBufferLastPos = -1;
-    int mActiveHistoryStates = 0xffffffff;
-    int mActiveHistoryStates2 = 0xffffffff;
-    long mLastHistoryElapsedRealtimeMs = 0;
-    long mTrackRunningHistoryElapsedRealtimeMs = 0;
-    long mTrackRunningHistoryUptimeMs = 0;
+    private boolean mHaveBatteryLevel = false;
+    private boolean mBatteryPluggedIn;
+    private int mBatteryStatus;
+    private int mBatteryLevel;
+    private int mBatteryPlugType;
+    private int mBatteryChargeUah;
+    private int mBatteryHealth;
+    private int mBatteryTemperature;
+    private int mBatteryVoltageMv = -1;
 
     @NonNull
-    final BatteryStatsHistory mBatteryStatsHistory;
-
-    final HistoryItem mHistoryCur = new HistoryItem();
-
-    // Used by computeHistoryStepDetails
-    HistoryStepDetails mLastHistoryStepDetails = null;
-    byte mLastHistoryStepLevel = 0;
-    final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
-    final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
-
-    /**
-     * Total time (in milliseconds) spent executing in user code.
-     */
-    long mLastStepCpuUserTimeMs;
-    long mCurStepCpuUserTimeMs;
-    /**
-     * Total time (in milliseconds) spent executing in kernel code.
-     */
-    long mLastStepCpuSystemTimeMs;
-    long mCurStepCpuSystemTimeMs;
-    /**
-     * Times from /proc/stat (but measured in milliseconds).
-     */
-    long mLastStepStatUserTimeMs;
-    long mLastStepStatSystemTimeMs;
-    long mLastStepStatIOWaitTimeMs;
-    long mLastStepStatIrqTimeMs;
-    long mLastStepStatSoftIrqTimeMs;
-    long mLastStepStatIdleTimeMs;
-    long mCurStepStatUserTimeMs;
-    long mCurStepStatSystemTimeMs;
-    long mCurStepStatIOWaitTimeMs;
-    long mCurStepStatIrqTimeMs;
-    long mCurStepStatSoftIrqTimeMs;
-    long mCurStepStatIdleTimeMs;
+    private final BatteryStatsHistory mHistory;
 
     private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator;
 
@@ -1391,7 +1352,6 @@
     int mDischargeUnplugLevel;
     int mDischargePlugLevel;
     int mDischargeCurrentLevel;
-    int mCurrentBatteryLevel;
     int mLowDischargeAmountSinceCharge;
     int mHighDischargeAmountSinceCharge;
     int mDischargeScreenOnUnplugLevel;
@@ -1443,7 +1403,6 @@
 
     private int mNumConnectivityChange;
 
-    private int mBatteryVoltageMv = -1;
     private int mEstimatedBatteryCapacityMah = -1;
 
     private int mLastLearnedBatteryCapacityUah = -1;
@@ -1627,28 +1586,27 @@
     }
 
     public BatteryStatsImpl(Clock clock) {
-        this(clock, (File) null);
+        this(clock, null);
     }
 
     public BatteryStatsImpl(Clock clock, File historyDirectory) {
         init(clock);
+        mHandler = null;
+        mConstants = new Constants(mHandler);
         mStartClockTimeMs = clock.currentTimeMillis();
         mCheckinFile = null;
         mDailyFile = null;
         if (historyDirectory == null) {
             mStatsFile = null;
-            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
+            mHistory = new BatteryStatsHistory(mStepDetailsCalculator, mClock);
         } else {
             mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
-            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer, historyDirectory,
-                    this::getMaxHistoryFiles);
+            mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES,
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock);
         }
-        mHandler = null;
         mPlatformIdleStateCallback = null;
         mMeasuredEnergyRetriever = null;
         mUserInfoProvider = null;
-        mConstants = new Constants(mHandler);
-        clearHistoryLocked();
     }
 
     private void init(Clock clock) {
@@ -3911,406 +3869,188 @@
         return kmt;
     }
 
-    /**
-     * Returns the index for the specified tag. If this is the first time the tag is encountered
-     * while writing the current history buffer, the method returns
-     * <code>(index | TAG_FIRST_OCCURRENCE_FLAG)</code>
-     */
-    private int writeHistoryTag(HistoryTag tag) {
-        if (tag.string == null) {
-            Slog.wtfStack(TAG, "writeHistoryTag called with null name");
-        }
+    private class HistoryStepDetailsCalculatorImpl implements HistoryStepDetailsCalculator {
+        private final HistoryStepDetails mDetails = new HistoryStepDetails();
 
-        final int stringLength = tag.string.length();
-        if (stringLength > MAX_HISTORY_TAG_STRING_LENGTH) {
-            Slog.e(TAG, "Long battery history tag: " + tag.string);
-            tag.string = tag.string.substring(0, MAX_HISTORY_TAG_STRING_LENGTH);
-        }
+        private boolean mHasHistoryStepDetails;
 
-        Integer idxObj = mHistoryTagPool.get(tag);
-        int idx;
-        if (idxObj != null) {
-            idx = idxObj;
-            if ((idx & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
-                mHistoryTagPool.put(tag, idx & ~BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG);
+        private int mLastHistoryStepLevel;
+
+        /**
+         * Total time (in milliseconds) spent executing in user code.
+         */
+        private long mLastStepCpuUserTimeMs;
+        private long mCurStepCpuUserTimeMs;
+        /**
+         * Total time (in milliseconds) spent executing in kernel code.
+         */
+        private long mLastStepCpuSystemTimeMs;
+        private long mCurStepCpuSystemTimeMs;
+        /**
+         * Times from /proc/stat (but measured in milliseconds).
+         */
+        private long mLastStepStatUserTimeMs;
+        private long mLastStepStatSystemTimeMs;
+        private long mLastStepStatIOWaitTimeMs;
+        private long mLastStepStatIrqTimeMs;
+        private long mLastStepStatSoftIrqTimeMs;
+        private long mLastStepStatIdleTimeMs;
+        private long mCurStepStatUserTimeMs;
+        private long mCurStepStatSystemTimeMs;
+        private long mCurStepStatIOWaitTimeMs;
+        private long mCurStepStatIrqTimeMs;
+        private long mCurStepStatSoftIrqTimeMs;
+        private long mCurStepStatIdleTimeMs;
+
+        @Override
+        public HistoryStepDetails getHistoryStepDetails() {
+            if (mBatteryLevel >= mLastHistoryStepLevel && mHasHistoryStepDetails) {
+                mLastHistoryStepLevel = mBatteryLevel;
+                return null;
             }
-            return idx;
-        } else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) {
-            idx = mNextHistoryTagIdx;
-            HistoryTag key = new HistoryTag();
-            key.setTo(tag);
-            tag.poolIdx = idx;
-            mHistoryTagPool.put(key, idx);
-            mNextHistoryTagIdx++;
 
-            mNumHistoryTagChars += stringLength + 1;
-            if (mHistoryTags != null) {
-                mHistoryTags.put(idx, key);
-            }
-            return idx | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG;
-        } else {
-            // Tag pool overflow: include the tag itself in the parcel
-            return HISTORY_TAG_INDEX_LIMIT | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG;
-        }
-    }
+            // Perform a CPU update right after we do this collection, so we have started
+            // collecting good data for the next step.
+            requestImmediateCpuUpdate();
 
-    /*
-        The history delta format uses flags to denote further data in subsequent ints in the parcel.
-
-        There is always the first token, which may contain the delta time, or an indicator of
-        the length of the time (int or long) following this token.
-
-        First token: always present,
-        31              23              15               7             0
-        █M|L|K|J|I|H|G|F█E|D|C|B|A|T|T|T█T|T|T|T|T|T|T|T█T|T|T|T|T|T|T|T█
-
-        T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
-           follows containing the time, and 0x7ffff indicates a long immediately follows with the
-           delta time.
-        A: battery level changed and an int follows with battery data.
-        B: state changed and an int follows with state change data.
-        C: state2 has changed and an int follows with state2 change data.
-        D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
-        E: event data has changed and an event struct follows.
-        F: battery charge in coulombs has changed and an int with the charge follows.
-        G: state flag denoting that the mobile radio was active.
-        H: state flag denoting that the wifi radio was active.
-        I: state flag denoting that a wifi scan occurred.
-        J: state flag denoting that a wifi full lock was held.
-        K: state flag denoting that the gps was on.
-        L: state flag denoting that a wakelock was held.
-        M: state flag denoting that the cpu was running.
-
-        Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
-        with the time delta.
-
-        Battery level int: if A in the first token is set,
-        31              23              15               7             0
-        █L|L|L|L|L|L|L|T█T|T|T|T|T|T|T|T█T|V|V|V|V|V|V|V█V|V|V|V|V|V|V|D█
-
-        D: indicates that extra history details follow.
-        V: the battery voltage.
-        T: the battery temperature.
-        L: the battery level (out of 100).
-
-        State change int: if B in the first token is set,
-        31              23              15               7             0
-        █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █
-
-        A: wifi multicast was on.
-        B: battery was plugged in.
-        C: screen was on.
-        D: phone was scanning for signal.
-        E: audio was on.
-        F: a sensor was active.
-
-        State2 change int: if C in the first token is set,
-        31              23              15               7             0
-        █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█
-
-        A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
-        B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
-        C: a bluetooth scan was active.
-        D: the camera was active.
-        E: bluetooth was on.
-        F: a phone call was active.
-        G: the device was charging.
-        H: 2 bits indicating the device-idle (doze) state: off, light, full
-        I: the flashlight was on.
-        J: wifi was on.
-        K: wifi was running.
-        L: video was playing.
-        M: power save mode was on.
-
-        Wakelock/wakereason struct: if D in the first token is set,
-        TODO(adamlesinski): describe wakelock/wakereason struct.
-
-        Event struct: if E in the first token is set,
-        TODO(adamlesinski): describe the event struct.
-
-        History step details struct: if D in the battery level int is set,
-        TODO(adamlesinski): describe the history step details struct.
-
-        Battery charge int: if F in the first token is set, an int representing the battery charge
-        in coulombs follows.
-     */
-
-    @GuardedBy("this")
-    public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
-        if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
-            dest.writeInt(BatteryStatsHistory.DELTA_TIME_ABS);
-            cur.writeToParcel(dest, 0);
-            return;
-        }
-
-        final long deltaTime = cur.time - last.time;
-        final int lastBatteryLevelInt = buildBatteryLevelInt(last);
-        final int lastStateInt = buildStateInt(last);
-
-        int deltaTimeToken;
-        if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
-            deltaTimeToken = BatteryStatsHistory.DELTA_TIME_LONG;
-        } else if (deltaTime >= BatteryStatsHistory.DELTA_TIME_ABS) {
-            deltaTimeToken = BatteryStatsHistory.DELTA_TIME_INT;
-        } else {
-            deltaTimeToken = (int)deltaTime;
-        }
-        int firstToken = deltaTimeToken | (cur.states & BatteryStatsHistory.DELTA_STATE_MASK);
-        final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
-                ? BatteryStatsHistory.BATTERY_DELTA_LEVEL_FLAG : 0;
-        final boolean computeStepDetails = includeStepDetails != 0
-                || mLastHistoryStepDetails == null;
-        final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
-        final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
-        if (batteryLevelIntChanged) {
-            firstToken |= BatteryStatsHistory.DELTA_BATTERY_LEVEL_FLAG;
-        }
-        final int stateInt = buildStateInt(cur);
-        final boolean stateIntChanged = stateInt != lastStateInt;
-        if (stateIntChanged) {
-            firstToken |= BatteryStatsHistory.DELTA_STATE_FLAG;
-        }
-        final boolean state2IntChanged = cur.states2 != last.states2;
-        if (state2IntChanged) {
-            firstToken |= BatteryStatsHistory.DELTA_STATE2_FLAG;
-        }
-        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
-            firstToken |= BatteryStatsHistory.DELTA_WAKELOCK_FLAG;
-        }
-        if (cur.eventCode != HistoryItem.EVENT_NONE) {
-            firstToken |= BatteryStatsHistory.DELTA_EVENT_FLAG;
-        }
-
-        final boolean batteryChargeChanged = cur.batteryChargeUah != last.batteryChargeUah;
-        if (batteryChargeChanged) {
-            firstToken |= BatteryStatsHistory.DELTA_BATTERY_CHARGE_FLAG;
-        }
-        dest.writeInt(firstToken);
-        if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
-                + " deltaTime=" + deltaTime);
-
-        if (deltaTimeToken >= BatteryStatsHistory.DELTA_TIME_INT) {
-            if (deltaTimeToken == BatteryStatsHistory.DELTA_TIME_INT) {
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
-                dest.writeInt((int)deltaTime);
-            } else {
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
-                dest.writeLong(deltaTime);
-            }
-        }
-        if (batteryLevelIntChanged) {
-            dest.writeInt(batteryLevelInt);
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
-                    + Integer.toHexString(batteryLevelInt)
-                    + " batteryLevel=" + cur.batteryLevel
-                    + " batteryTemp=" + cur.batteryTemperature
-                    + " batteryVolt=" + (int)cur.batteryVoltage);
-        }
-        if (stateIntChanged) {
-            dest.writeInt(stateInt);
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
-                    + Integer.toHexString(stateInt)
-                    + " batteryStatus=" + cur.batteryStatus
-                    + " batteryHealth=" + cur.batteryHealth
-                    + " batteryPlugType=" + cur.batteryPlugType
-                    + " states=0x" + Integer.toHexString(cur.states));
-        }
-        if (state2IntChanged) {
-            dest.writeInt(cur.states2);
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
-                    + Integer.toHexString(cur.states2));
-        }
-        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
-            int wakeLockIndex;
-            int wakeReasonIndex;
-            if (cur.wakelockTag != null) {
-                wakeLockIndex = writeHistoryTag(cur.wakelockTag);
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
-                    + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
-            } else {
-                wakeLockIndex = 0xffff;
-            }
-            if (cur.wakeReasonTag != null) {
-                wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
-                    + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
-            } else {
-                wakeReasonIndex = 0xffff;
-            }
-            dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
-            if (cur.wakelockTag != null
-                    && (wakeLockIndex & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
-                cur.wakelockTag.writeToParcel(dest, 0);
-                cur.tagsFirstOccurrence = true;
-            }
-            if (cur.wakeReasonTag != null
-                    && (wakeReasonIndex & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
-                cur.wakeReasonTag.writeToParcel(dest, 0);
-                cur.tagsFirstOccurrence = true;
-            }
-        }
-        if (cur.eventCode != HistoryItem.EVENT_NONE) {
-            final int index = writeHistoryTag(cur.eventTag);
-            final int codeAndIndex = (cur.eventCode & 0xffff) | (index << 16);
-            dest.writeInt(codeAndIndex);
-            if ((index & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
-                cur.eventTag.writeToParcel(dest, 0);
-                cur.tagsFirstOccurrence = true;
-            }
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
-                    + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
-                    + cur.eventTag.string);
-        }
-        if (computeStepDetails) {
             if (mPlatformIdleStateCallback != null) {
-                mCurHistoryStepDetails.statSubsystemPowerState =
+                mDetails.statSubsystemPowerState =
                         mPlatformIdleStateCallback.getSubsystemLowPowerStats();
                 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
-                        mCurHistoryStepDetails.statSubsystemPowerState);
-
+                        mDetails.statSubsystemPowerState);
             }
-            computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
-            if (includeStepDetails != 0) {
-                mCurHistoryStepDetails.writeToParcel(dest);
-            }
-            cur.stepDetails = mCurHistoryStepDetails;
-            mLastHistoryStepDetails = mCurHistoryStepDetails;
-        } else {
-            cur.stepDetails = null;
-        }
-        if (mLastHistoryStepLevel < cur.batteryLevel) {
-            mLastHistoryStepDetails = null;
-        }
-        mLastHistoryStepLevel = cur.batteryLevel;
 
-        if (batteryChargeChanged) {
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUah=" + cur.batteryChargeUah);
-            dest.writeInt(cur.batteryChargeUah);
-        }
-        dest.writeDouble(cur.modemRailChargeMah);
-        dest.writeDouble(cur.wifiRailChargeMah);
-    }
-
-    private int buildBatteryLevelInt(HistoryItem h) {
-        return ((((int)h.batteryLevel)<<25)&0xfe000000)
-                | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
-                | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
-    }
-
-    private int buildStateInt(HistoryItem h) {
-        int plugType = 0;
-        if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
-            plugType = 1;
-        } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
-            plugType = 2;
-        } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
-            plugType = 3;
-        }
-        return ((h.batteryStatus & BatteryStatsHistory.STATE_BATTERY_STATUS_MASK)
-                << BatteryStatsHistory.STATE_BATTERY_STATUS_SHIFT)
-                | ((h.batteryHealth & BatteryStatsHistory.STATE_BATTERY_HEALTH_MASK)
-                << BatteryStatsHistory.STATE_BATTERY_HEALTH_SHIFT)
-                | ((plugType & BatteryStatsHistory.STATE_BATTERY_PLUG_MASK)
-                << BatteryStatsHistory.STATE_BATTERY_PLUG_SHIFT)
-                | (h.states & (~BatteryStatsHistory.STATE_BATTERY_MASK));
-    }
-
-    private void computeHistoryStepDetails(final HistoryStepDetails out,
-            final HistoryStepDetails last) {
-        final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
-
-        // Perform a CPU update right after we do this collection, so we have started
-        // collecting good data for the next step.
-        requestImmediateCpuUpdate();
-
-        if (last == null) {
-            // We are not generating a delta, so all we need to do is reset the stats
-            // we will later be doing a delta from.
-            final int NU = mUidStats.size();
-            for (int i=0; i<NU; i++) {
-                final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
-                uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
-                uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
-            }
-            mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
-            mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
-            mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
-            mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
-            mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
-            mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
-            mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
-            mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
-            tmp.clear();
-            return;
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys="
-                    + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs
-                    + " irq=" + mLastStepStatIrqTimeMs + " sirq="
-                    + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs);
-            Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys="
-                    + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs
-                    + " irq=" + mCurStepStatIrqTimeMs + " sirq="
-                    + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs);
-        }
-        out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs);
-        out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs);
-        out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs);
-        out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs);
-        out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs);
-        out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs);
-        out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs);
-        out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs);
-        out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
-        out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
-        out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
-        final int NU = mUidStats.size();
-        for (int i=0; i<NU; i++) {
-            final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
-            final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs);
-            final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs);
-            final int totalTimeMs = totalUTimeMs + totalSTimeMs;
-            uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
-            uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
-            if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) {
-                continue;
-            }
-            if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) {
-                out.appCpuUid3 = uid.mUid;
-                out.appCpuUTime3 = totalUTimeMs;
-                out.appCpuSTime3 = totalSTimeMs;
-            } else {
-                out.appCpuUid3 = out.appCpuUid2;
-                out.appCpuUTime3 = out.appCpuUTime2;
-                out.appCpuSTime3 = out.appCpuSTime2;
-                if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) {
-                    out.appCpuUid2 = uid.mUid;
-                    out.appCpuUTime2 = totalUTimeMs;
-                    out.appCpuSTime2 = totalSTimeMs;
-                } else {
-                    out.appCpuUid2 = out.appCpuUid1;
-                    out.appCpuUTime2 = out.appCpuUTime1;
-                    out.appCpuSTime2 = out.appCpuSTime1;
-                    out.appCpuUid1 = uid.mUid;
-                    out.appCpuUTime1 = totalUTimeMs;
-                    out.appCpuSTime1 = totalSTimeMs;
+            if (!mHasHistoryStepDetails) {
+                // We are not generating a delta, so all we need to do is reset the stats
+                // we will later be doing a delta from.
+                final int uidCount = mUidStats.size();
+                for (int i = 0; i < uidCount; i++) {
+                    final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+                    uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
+                    uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
                 }
+                mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
+                mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
+                mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
+                mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
+                mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
+                mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
+                mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
+                mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
+                mDetails.clear();
+            } else {
+                if (DEBUG) {
+                    Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys="
+                            + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs
+                            + " irq=" + mLastStepStatIrqTimeMs + " sirq="
+                            + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs);
+                    Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys="
+                            + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs
+                            + " irq=" + mCurStepStatIrqTimeMs + " sirq="
+                            + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs);
+                }
+                mDetails.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs);
+                mDetails.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs);
+                mDetails.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs);
+                mDetails.statSystemTime =
+                        (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs);
+                mDetails.statIOWaitTime =
+                        (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs);
+                mDetails.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs);
+                mDetails.statSoftIrqTime =
+                        (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs);
+                mDetails.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs);
+                mDetails.appCpuUid1 = mDetails.appCpuUid2 = mDetails.appCpuUid3 = -1;
+                mDetails.appCpuUTime1 = mDetails.appCpuUTime2 = mDetails.appCpuUTime3 = 0;
+                mDetails.appCpuSTime1 = mDetails.appCpuSTime2 = mDetails.appCpuSTime3 = 0;
+                final int uidCount = mUidStats.size();
+                for (int i = 0; i < uidCount; i++) {
+                    final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+                    final int totalUTimeMs =
+                            (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs);
+                    final int totalSTimeMs =
+                            (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs);
+                    final int totalTimeMs = totalUTimeMs + totalSTimeMs;
+                    uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs;
+                    uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs;
+                    if (totalTimeMs <= (mDetails.appCpuUTime3 + mDetails.appCpuSTime3)) {
+                        continue;
+                    }
+                    if (totalTimeMs <= (mDetails.appCpuUTime2 + mDetails.appCpuSTime2)) {
+                        mDetails.appCpuUid3 = uid.mUid;
+                        mDetails.appCpuUTime3 = totalUTimeMs;
+                        mDetails.appCpuSTime3 = totalSTimeMs;
+                    } else {
+                        mDetails.appCpuUid3 = mDetails.appCpuUid2;
+                        mDetails.appCpuUTime3 = mDetails.appCpuUTime2;
+                        mDetails.appCpuSTime3 = mDetails.appCpuSTime2;
+                        if (totalTimeMs <= (mDetails.appCpuUTime1 + mDetails.appCpuSTime1)) {
+                            mDetails.appCpuUid2 = uid.mUid;
+                            mDetails.appCpuUTime2 = totalUTimeMs;
+                            mDetails.appCpuSTime2 = totalSTimeMs;
+                        } else {
+                            mDetails.appCpuUid2 = mDetails.appCpuUid1;
+                            mDetails.appCpuUTime2 = mDetails.appCpuUTime1;
+                            mDetails.appCpuSTime2 = mDetails.appCpuSTime1;
+                            mDetails.appCpuUid1 = uid.mUid;
+                            mDetails.appCpuUTime1 = totalUTimeMs;
+                            mDetails.appCpuSTime1 = totalSTimeMs;
+                        }
+                    }
+                }
+                mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
+                mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
+                mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
+                mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
+                mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
+                mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
+                mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
+                mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
             }
+
+            mHasHistoryStepDetails = mBatteryLevel <= mLastHistoryStepLevel;
+            mLastHistoryStepLevel = mBatteryLevel;
+
+            return mDetails;
         }
-        mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
-        mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
-        mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
-        mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
-        mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
-        mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
-        mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
-        mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
+
+        public void addCpuStats(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs,
+                int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs,
+                int statSoftIrqTimeMs, int statIdleTimeMs) {
+            if (DEBUG) {
+                Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs
+                        + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs
+                        + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs
+                        + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs);
+            }
+            mCurStepCpuUserTimeMs += totalUTimeMs;
+            mCurStepCpuSystemTimeMs += totalSTimeMs;
+            mCurStepStatUserTimeMs += statUserTimeMs;
+            mCurStepStatSystemTimeMs += statSystemTimeMs;
+            mCurStepStatIOWaitTimeMs += statIOWaitTimeMs;
+            mCurStepStatIrqTimeMs += statIrqTimeMs;
+            mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs;
+            mCurStepStatIdleTimeMs += statIdleTimeMs;
+        }
+
+        @Override
+        public void clear() {
+            mHasHistoryStepDetails = false;
+            mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0;
+            mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0;
+            mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0;
+            mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0;
+            mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0;
+            mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0;
+            mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0;
+            mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0;
+        }
     }
 
     @GuardedBy("this")
     @Override
     public void commitCurrentHistoryBatchLocked() {
-        mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
+        mHistory.commitCurrentHistoryBatchLocked();
     }
 
     @GuardedBy("this")
@@ -4326,191 +4066,9 @@
     }
 
     @GuardedBy("this")
-    void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
-        if (!mHaveBatteryLevel || !mRecordingHistory) {
-            return;
-        }
-
-        final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time;
-        final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
-        final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
-        final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
-        final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
-        if (DEBUG) {
-            Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff="
-                    + Integer.toHexString(diffStates) + " lastDiff="
-                    + Integer.toHexString(lastDiffStates) + " diff2="
-                    + Integer.toHexString(diffStates2) + " lastDiff2="
-                    + Integer.toHexString(lastDiffStates2));
-        }
-        if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
-                && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0
-                && (diffStates2&lastDiffStates2) == 0
-                && (!mHistoryLastWritten.tagsFirstOccurrence && !cur.tagsFirstOccurrence)
-                && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
-                && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
-                && mHistoryLastWritten.stepDetails == null
-                && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
-                        || cur.eventCode == HistoryItem.EVENT_NONE)
-                && mHistoryLastWritten.batteryLevel == cur.batteryLevel
-                && mHistoryLastWritten.batteryStatus == cur.batteryStatus
-                && mHistoryLastWritten.batteryHealth == cur.batteryHealth
-                && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
-                && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
-                && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
-            // We can merge this new change in with the last one.  Merging is
-            // allowed as long as only the states have changed, and within those states
-            // 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);
-            mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
-            mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
-            mHistoryBufferLastPos = -1;
-            elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs;
-            // If the last written history had a wakelock tag, we need to retain it.
-            // Note that the condition above made sure that we aren't in a case where
-            // both it and the current history item have a wakelock tag.
-            if (mHistoryLastWritten.wakelockTag != null) {
-                cur.wakelockTag = cur.localWakelockTag;
-                cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
-            }
-            // If the last written history had a wake reason tag, we need to retain it.
-            // Note that the condition above made sure that we aren't in a case where
-            // both it and the current history item have a wakelock tag.
-            if (mHistoryLastWritten.wakeReasonTag != null) {
-                cur.wakeReasonTag = cur.localWakeReasonTag;
-                cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
-            }
-            // If the last written history had an event, we need to retain it.
-            // Note that the condition above made sure that we aren't in a case where
-            // both it and the current history item have an event.
-            if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
-                cur.eventCode = mHistoryLastWritten.eventCode;
-                cur.eventTag = cur.localEventTag;
-                cur.eventTag.setTo(mHistoryLastWritten.eventTag);
-            }
-            mHistoryLastWritten.setTo(mHistoryLastLastWritten);
-        }
-        final int dataSize = mHistoryBuffer.dataSize();
-
-        if (dataSize >= mConstants.MAX_HISTORY_BUFFER) {
-            //open a new history file.
-            final long start = SystemClock.uptimeMillis();
-            writeHistoryLocked();
-            if (DEBUG) {
-                Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:"
-                        + (SystemClock.uptimeMillis() - start));
-            }
-            mBatteryStatsHistory.startNextFile();
-            mHistoryBuffer.setDataSize(0);
-            mHistoryBuffer.setDataPosition(0);
-            mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2);
-            mHistoryBufferLastPos = -1;
-            mHistoryLastWritten.clear();
-            mHistoryLastLastWritten.clear();
-
-            // Mark every entry in the pool with a flag indicating that the tag
-            // has not yet been encountered while writing the current history buffer.
-            for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) {
-                entry.setValue(entry.getValue() | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG);
-            }
-            // Make a copy of mHistoryCur.
-            HistoryItem copy = new HistoryItem();
-            copy.setTo(cur);
-            // startRecordingHistory will reset mHistoryCur.
-            startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
-            // Add the copy into history buffer.
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, copy);
-            return;
-        }
-
-        if (dataSize == 0) {
-            // The history is currently empty; we need it to start with a time stamp.
-            cur.currentTime = mClock.currentTimeMillis();
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur);
-        }
-        addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
-    }
-
-    @GuardedBy("this")
-    private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) {
-        if (mBatteryStatsHistoryIterator != null) {
-            throw new IllegalStateException("Can't do this while iterating history!");
-        }
-        mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
-        mHistoryLastLastWritten.setTo(mHistoryLastWritten);
-        final boolean hasTags = mHistoryLastWritten.tagsFirstOccurrence || cur.tagsFirstOccurrence;
-        mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
-        mHistoryLastWritten.tagsFirstOccurrence = hasTags;
-        mHistoryLastWritten.states &= mActiveHistoryStates;
-        mHistoryLastWritten.states2 &= mActiveHistoryStates2;
-        writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
-        mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs;
-        cur.wakelockTag = null;
-        cur.wakeReasonTag = null;
-        cur.eventCode = HistoryItem.EVENT_NONE;
-        cur.eventTag = null;
-        cur.tagsFirstOccurrence = false;
-        if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
-                + " now " + mHistoryBuffer.dataPosition()
-                + " size is now " + mHistoryBuffer.dataSize());
-    }
-
-    @GuardedBy("this")
-    void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
-        if (mTrackRunningHistoryElapsedRealtimeMs != 0) {
-            final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs;
-            final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs;
-            if (diffUptimeMs < (diffElapsedMs - 20)) {
-                final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs);
-                mHistoryAddTmp.setTo(mHistoryLastWritten);
-                mHistoryAddTmp.wakelockTag = null;
-                mHistoryAddTmp.wakeReasonTag = null;
-                mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
-                mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
-                addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp);
-            }
-        }
-        mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
-        mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs;
-        mTrackRunningHistoryUptimeMs = uptimeMs;
-        addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
-    }
-
-    @GuardedBy("this")
-    void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
-        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
-    }
-
-    @GuardedBy("this")
-    public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
+    public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
             String name, int uid) {
-        mHistoryCur.eventCode = code;
-        mHistoryCur.eventTag = mHistoryCur.localEventTag;
-        mHistoryCur.eventTag.string = name;
-        mHistoryCur.eventTag.uid = uid;
-        addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
-    }
-
-    @GuardedBy("this")
-    void clearHistoryLocked() {
-        if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
-        mHistoryBaseTimeMs = 0;
-        mLastHistoryElapsedRealtimeMs = 0;
-        mTrackRunningHistoryElapsedRealtimeMs = 0;
-        mTrackRunningHistoryUptimeMs = 0;
-
-        mHistoryBuffer.setDataSize(0);
-        mHistoryBuffer.setDataPosition(0);
-        mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2);
-        mHistoryLastLastWritten.clear();
-        mHistoryLastWritten.clear();
-        mHistoryTagPool.clear();
-        mNextHistoryTagIdx = 0;
-        mNumHistoryTagChars = 0;
-        mHistoryBufferLastPos = -1;
-        mActiveHistoryStates = 0xffffffff;
-        mActiveHistoryStates2 = 0xffffffff;
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid);
     }
 
     @GuardedBy("this")
@@ -4663,13 +4221,13 @@
         if (!mActiveEvents.updateState(code, name, uid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid);
     }
 
     @GuardedBy("this")
     public void noteCurrentTimeChangedLocked(long currentTimeMs,
             long elapsedRealtimeMs, long uptimeMs) {
-        recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs);
+        mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs);
     }
 
     @GuardedBy("this")
@@ -4686,7 +4244,7 @@
         if (!mRecordAllHistory) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid);
     }
 
     @GuardedBy("this")
@@ -4744,8 +4302,7 @@
         if (!mRecordAllHistory) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH,
-                name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid);
     }
 
     @GuardedBy("this")
@@ -4761,7 +4318,7 @@
         if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid);
     }
 
     @GuardedBy("this")
@@ -4777,8 +4334,7 @@
         if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH,
-                name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid);
     }
 
     @GuardedBy("this")
@@ -4794,7 +4350,7 @@
         if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid);
     }
 
     @GuardedBy("this")
@@ -4812,7 +4368,7 @@
         if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid);
     }
 
     @GuardedBy("this")
@@ -4860,7 +4416,7 @@
             for (int i = 0; i < workSource.size(); ++i) {
                 uid = mapUid(workSource.getUid(i));
                 if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
-                    addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+                    mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
                 }
             }
 
@@ -4869,7 +4425,7 @@
                 for (int i = 0; i < workChains.size(); ++i) {
                     uid = mapUid(workChains.get(i).getAttributionUid());
                     if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
-                        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+                        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
                     }
                 }
             }
@@ -4877,7 +4433,7 @@
             uid = mapUid(uid);
 
             if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
-                addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+                mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
             }
         }
     }
@@ -4952,7 +4508,7 @@
                 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
                     SparseIntArray uids = ent.getValue();
                     for (int j=0; j<uids.size(); j++) {
-                        addHistoryEventLocked(mSecRealtime, mSecUptime,
+                        mHistory.recordEvent(mSecRealtime, mSecUptime,
                                 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
                     }
                 }
@@ -4967,8 +4523,8 @@
                 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
                     SparseIntArray uids = ent.getValue();
                     for (int j=0; j<uids.size(); j++) {
-                        addHistoryEventLocked(mSecRealtime, mSecUptime,
-                                HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
+                        mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START,
+                                ent.getKey(), uids.keyAt(j));
                     }
                 }
             }
@@ -5011,30 +4567,19 @@
             if (mRecordAllHistory) {
                 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
                         mappedUid, 0)) {
-                    addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
+                    mHistory.recordEvent(elapsedRealtimeMs, uptimeMs,
                             HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid);
                 }
             }
             if (mWakeLockNesting == 0) {
-                mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
-                        + Integer.toHexString(mHistoryCur.states));
-                mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                mHistoryCur.wakelockTag.string = historyName;
-                mHistoryCur.wakelockTag.uid = mappedUid;
                 mWakeLockImportant = !unimportantForLogging;
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
-            } else if (!mWakeLockImportant && !unimportantForLogging
-                    && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
-                if (mHistoryLastWritten.wakelockTag != null) {
-                    // We'll try to update the last tag.
-                    mHistoryLastWritten.wakelockTag = null;
-                    mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
-                    mHistoryCur.wakelockTag.string = historyName;
-                    mHistoryCur.wakelockTag.uid = mappedUid;
-                    addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName,
+                        mappedUid);
+            } else if (!mWakeLockImportant && !unimportantForLogging) {
+                if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName,
+                        mappedUid)) {
+                    mWakeLockImportant = true;
                 }
-                mWakeLockImportant = true;
             }
             mWakeLockNesting++;
         }
@@ -5087,15 +4632,13 @@
                 }
                 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
                         mappedUid, 0)) {
-                    addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
+                    mHistory.recordEvent(elapsedRealtimeMs, uptimeMs,
                             HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid);
                 }
             }
             if (mWakeLockNesting == 0) {
-                mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
-                        + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE_WAKE_LOCK_FLAG);
             }
         }
         if (mappedUid >= 0) {
@@ -5286,7 +4829,7 @@
                 mappedUid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
                 historyName, mappedUid);
         if (mappedUid != uid) {
             // Prevent the isolated uid mapping from being removed while the wakelock is
@@ -5339,7 +4882,7 @@
                 mappedUid, 0)) {
             return;
         }
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
                 historyName, mappedUid);
         if (mappedUid != uid) {
             // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
@@ -5361,15 +4904,10 @@
 
     @GuardedBy("this")
     public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
-        if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
-                + Integer.toHexString(mHistoryCur.states));
         aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
-        mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
-        mHistoryCur.wakeReasonTag.string = reason;
-        mHistoryCur.wakeReasonTag.uid = 0;
+        mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason);
         mLastWakeupReason = reason;
         mLastWakeupUptimeMs = uptimeMs;
-        addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
     }
 
     @GuardedBy("this")
@@ -5380,22 +4918,11 @@
 
     @GuardedBy("this")
     public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs,
-                                      int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs,
-                                      int statSoftIrqTimeMs, int statIdleTimeMs) {
-        if (DEBUG) {
-            Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs
-                    + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs
-                    + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs
-                    + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs);
-        }
-        mCurStepCpuUserTimeMs += totalUTimeMs;
-        mCurStepCpuSystemTimeMs += totalSTimeMs;
-        mCurStepStatUserTimeMs += statUserTimeMs;
-        mCurStepStatSystemTimeMs += statSystemTimeMs;
-        mCurStepStatIOWaitTimeMs += statIOWaitTimeMs;
-        mCurStepStatIrqTimeMs += statIrqTimeMs;
-        mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs;
-        mCurStepStatIdleTimeMs += statIdleTimeMs;
+            int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs,
+            int statSoftIrqTimeMs, int statIdleTimeMs) {
+        mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs,
+                statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs,
+                statSoftIrqTimeMs, statIdleTimeMs);
     }
 
     public void noteProcessDiedLocked(int uid, int pid) {
@@ -5425,10 +4952,8 @@
     public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mSensorNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_SENSOR_ON_FLAG);
         }
         mSensorNesting++;
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -5445,10 +4970,8 @@
         uid = mapUid(uid);
         mSensorNesting--;
         if (mSensorNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_SENSOR_ON_FLAG);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
                 .noteStopSensor(sensor, elapsedRealtimeMs);
@@ -5498,10 +5021,8 @@
         }
         final int mappedUid = mapUid(uid);
         if (mGpsNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_GPS_ON_FLAG);
         }
         mGpsNesting++;
 
@@ -5526,10 +5047,8 @@
         final int mappedUid = mapUid(uid);
         mGpsNesting--;
         if (mGpsNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_GPS_ON_FLAG);
             stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs);
             mGpsSignalQualityBin = -1;
         }
@@ -5562,12 +5081,9 @@
             if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) {
                 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs);
             }
-            mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
-                    | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel);
             mGpsSignalQualityBin = signalLevel;
         }
-        return;
     }
 
     @GuardedBy("this")
@@ -5740,41 +5256,33 @@
                 }
             }
 
-            boolean updateHistory = false;
+            int startStates = 0;
+            int stopStates = 0;
             if (Display.isDozeState(state) && !Display.isDozeState(oldState)) {
-                mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
+                startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
                 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs);
-                updateHistory = true;
             } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) {
-                mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG;
+                stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
                 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
-                updateHistory = true;
             }
             if (Display.isOnState(state)) {
-                mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
-                        + Integer.toHexString(mHistoryCur.states));
+                startStates |= HistoryItem.STATE_SCREEN_ON_FLAG;
                 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs);
                 if (mScreenBrightnessBin >= 0) {
                     mScreenBrightnessTimer[mScreenBrightnessBin]
                             .startRunningLocked(elapsedRealtimeMs);
                 }
-                updateHistory = true;
             } else if (Display.isOnState(oldState)) {
-                mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
-                        + Integer.toHexString(mHistoryCur.states));
+                stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG;
                 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs);
                 if (mScreenBrightnessBin >= 0) {
                     mScreenBrightnessTimer[mScreenBrightnessBin]
                             .stopRunningLocked(elapsedRealtimeMs);
                 }
-                updateHistory = true;
             }
-            if (updateHistory) {
-                if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: "
-                        + Display.stateToString(state));
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            if (startStates != 0 || stopStates != 0) {
+                mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates,
+                        stopStates);
             }
 
             // Per screen state Cpu stats needed. Prepare to schedule an external sync.
@@ -5888,13 +5396,7 @@
             long uptimeMs) {
         if (mScreenBrightnessBin != overallBin) {
             if (overallBin >= 0) {
-                mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK)
-                        | (overallBin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
-                if (DEBUG_HISTORY) {
-                    Slog.v(TAG, "Screen brightness " + overallBin + " to: "
-                            + Integer.toHexString(mHistoryCur.states));
-                }
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin);
             }
             if (mScreenState == Display.STATE_ON) {
                 if (mScreenBrightnessBin >= 0) {
@@ -5921,8 +5423,8 @@
     @GuardedBy("this")
     public void noteWakeUpLocked(String reason, int reasonUid,
             long elapsedRealtimeMs, long uptimeMs) {
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP,
-                reason, reasonUid);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason,
+                reasonUid);
     }
 
     @GuardedBy("this")
@@ -5941,7 +5443,7 @@
     @GuardedBy("this")
     public void noteConnectivityChangedLocked(int type, String extra,
             long elapsedRealtimeMs, long uptimeMs) {
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
                 extra, type);
         mNumConnectivityChange++;
     }
@@ -5950,7 +5452,7 @@
     private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis,
             final long uptimeMillis, int uid) {
         uid = mapUid(uid);
-        addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
+        mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
                 uid);
         getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked();
     }
@@ -5976,7 +5478,8 @@
                 }
 
                 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
-                mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG);
             } else {
                 realElapsedRealtimeMs = timestampNs / (1000*1000);
                 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs;
@@ -5988,11 +5491,9 @@
                     mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs
                             - realElapsedRealtimeMs);
                 }
-                mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG);
             }
-            if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
             mMobileRadioPowerState = powerState;
 
             // Inform current RatBatteryStats that the modem active state might have changed.
@@ -6042,17 +5543,14 @@
             mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
             mPowerSaveModeEnabled = enabled;
             if (enabled) {
-                mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
-                        + Integer.toHexString(mHistoryCur.states2));
+                mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE2_POWER_SAVE_FLAG);
                 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs);
             } else {
-                mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
-                        + Integer.toHexString(mHistoryCur.states2));
+                mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE2_POWER_SAVE_FLAG);
                 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs);
             }
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
             FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED,
                     enabled
                         ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON
@@ -6076,7 +5574,7 @@
             nowLightIdling = true;
         }
         if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
-            addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE,
+            mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE,
                     activeReason, activeUid);
         }
         if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) {
@@ -6106,11 +5604,7 @@
             }
         }
         if (mDeviceIdleMode != mode) {
-            mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
-                    | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, mode);
             long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs;
             mLastIdleTimeStartMs = elapsedRealtimeMs;
             if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
@@ -6138,7 +5632,7 @@
     public void notePackageInstalledLocked(String pkgName, long versionCode,
             long elapsedRealtimeMs, long uptimeMs) {
         // XXX need to figure out what to do with long version codes.
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED,
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED,
                 pkgName, (int)versionCode);
         PackageChange pc = new PackageChange();
         pc.mPackageName = pkgName;
@@ -6150,8 +5644,8 @@
     @GuardedBy("this")
     public void notePackageUninstalledLocked(String pkgName,
             long elapsedRealtimeMs, long uptimeMs) {
-        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
-                HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0);
+        mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
+                pkgName, 0);
         PackageChange pc = new PackageChange();
         pc.mPackageName = pkgName;
         pc.mUpdate = true;
@@ -6180,10 +5674,8 @@
     @GuardedBy("this")
     public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (!mPhoneOn) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_PHONE_IN_CALL_FLAG);
             mPhoneOn = true;
             mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs);
         }
@@ -6192,10 +5684,8 @@
     @GuardedBy("this")
     public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mPhoneOn) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_PHONE_IN_CALL_FLAG);
             mPhoneOn = false;
             mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs);
         }
@@ -6233,11 +5723,12 @@
         if (mUsbDataState != newState) {
             mUsbDataState = newState;
             if (connected) {
-                mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+                mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE2_USB_DATA_LINK_FLAG);
             } else {
-                mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+                mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE2_USB_DATA_LINK_FLAG);
             }
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
         }
     }
 
@@ -6258,6 +5749,10 @@
             long elapsedRealtimeMs, long uptimeMs) {
         boolean scanning = false;
         boolean newHistory = false;
+        int addStateFlag = 0;
+        int removeStateFlag = 0;
+        int newState = -1;
+        int newSignalStrength = -1;
 
         mPhoneServiceStateRaw = state;
         mPhoneSimStateRaw = simState;
@@ -6286,10 +5781,8 @@
             scanning = true;
             strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
             if (!mPhoneSignalScanningTimer.isRunningLocked()) {
-                mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
+                addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 newHistory = true;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
-                        + Integer.toHexString(mHistoryCur.states));
                 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs);
                 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state,
                         simState, strengthBin);
@@ -6299,9 +5792,7 @@
         if (!scanning) {
             // If we are no longer scanning, then stop the scanning timer.
             if (mPhoneSignalScanningTimer.isRunningLocked()) {
-                mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
-                if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
-                        + Integer.toHexString(mHistoryCur.states));
+                removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 newHistory = true;
                 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs);
                 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state,
@@ -6310,10 +5801,7 @@
         }
 
         if (mPhoneServiceState != state) {
-            mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
-                    | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
+            newState = state;
             newHistory = true;
             mPhoneServiceState = state;
         }
@@ -6327,11 +5815,7 @@
                 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
                     mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
                 }
-                mHistoryCur.states =
-                        (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
-                        | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
-                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
-                        + Integer.toHexString(mHistoryCur.states));
+                newSignalStrength = strengthBin;
                 newHistory = true;
                 FrameworkStatsLog.write(
                         FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin);
@@ -6342,7 +5826,8 @@
         }
 
         if (newHistory) {
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs,
+                    addStateFlag, removeStateFlag, newState, newSignalStrength);
         }
     }
 
@@ -6466,11 +5951,7 @@
 
         if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
         if (mPhoneDataConnectionType != bin) {
-            mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
-                    | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, bin);
             if (mPhoneDataConnectionType >= 0) {
                 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
                         elapsedRealtimeMs);
@@ -6543,10 +6024,8 @@
     @GuardedBy("this")
     public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (!mWifiOn) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_WIFI_ON_FLAG);
             mWifiOn = true;
             mWifiOnTimer.startRunningLocked(elapsedRealtimeMs);
             scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
@@ -6556,10 +6035,8 @@
     @GuardedBy("this")
     public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mWifiOn) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_WIFI_ON_FLAG);
             mWifiOn = false;
             mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs);
             scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
@@ -6570,10 +6047,8 @@
     public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mAudioOnNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_AUDIO_ON_FLAG);
             mAudioOnTimer.startRunningLocked(elapsedRealtimeMs);
         }
         mAudioOnNesting++;
@@ -6588,10 +6063,8 @@
         }
         uid = mapUid(uid);
         if (--mAudioOnNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_AUDIO_ON_FLAG);
             mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6602,10 +6075,8 @@
     public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mVideoOnNesting == 0) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_VIDEO_ON_FLAG);
             mVideoOnTimer.startRunningLocked(elapsedRealtimeMs);
         }
         mVideoOnNesting++;
@@ -6620,10 +6091,8 @@
         }
         uid = mapUid(uid);
         if (--mVideoOnNesting == 0) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_VIDEO_ON_FLAG);
             mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6634,10 +6103,8 @@
     public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mAudioOnNesting > 0) {
             mAudioOnNesting = 0;
-            mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_AUDIO_ON_FLAG);
             mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
             for (int i=0; i<mUidStats.size(); i++) {
                 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6650,10 +6117,8 @@
     public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mVideoOnNesting > 0) {
             mVideoOnNesting = 0;
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_VIDEO_ON_FLAG);
             mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
             for (int i=0; i<mUidStats.size(); i++) {
                 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6705,10 +6170,8 @@
     public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mFlashlightOnNesting++ == 0) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_FLASHLIGHT_FLAG);
             mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6722,10 +6185,8 @@
         }
         uid = mapUid(uid);
         if (--mFlashlightOnNesting == 0) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_FLASHLIGHT_FLAG);
             mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6736,10 +6197,8 @@
     public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mCameraOnNesting++ == 0) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_CAMERA_FLAG);
             mCameraOnTimer.startRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6753,10 +6212,8 @@
         }
         uid = mapUid(uid);
         if (--mCameraOnNesting == 0) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_CAMERA_FLAG);
             mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6767,10 +6224,8 @@
     public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mCameraOnNesting > 0) {
             mCameraOnNesting = 0;
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_CAMERA_FLAG);
             mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
             for (int i=0; i<mUidStats.size(); i++) {
                 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6783,10 +6238,8 @@
     public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mFlashlightOnNesting > 0) {
             mFlashlightOnNesting = 0;
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_FLASHLIGHT_FLAG);
             mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
             for (int i=0; i<mUidStats.size(); i++) {
                 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6803,10 +6256,8 @@
         }
         uid = mapUid(uid);
         if (mBluetoothScanNesting == 0) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
             mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs);
         }
         mBluetoothScanNesting++;
@@ -6847,10 +6298,8 @@
         uid = mapUid(uid);
         mBluetoothScanNesting--;
         if (mBluetoothScanNesting == 0) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
             mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6885,10 +6334,8 @@
     public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) {
         if (mBluetoothScanNesting > 0) {
             mBluetoothScanNesting = 0;
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
             mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
             for (int i=0; i<mUidStats.size(); i++) {
                 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6928,7 +6375,7 @@
     private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
             final long uptimeMillis, int uid) {
         uid = mapUid(uid);
-        addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
+        mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
                 uid);
         getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked();
     }
@@ -6944,15 +6391,14 @@
                 if (uid > 0) {
                     noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid);
                 }
-                mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
+                mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG);
                 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs);
             } else {
-                mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
+                mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                        HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG);
                 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000));
             }
-            if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
             mWifiRadioPowerState = powerState;
         }
     }
@@ -6960,10 +6406,8 @@
     @GuardedBy("this")
     public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
         if (!mGlobalWifiRunning) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_WIFI_RUNNING_FLAG);
             mGlobalWifiRunning = true;
             mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
             int N = ws.size();
@@ -7031,10 +6475,8 @@
     @GuardedBy("this")
     public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
         if (mGlobalWifiRunning) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_WIFI_RUNNING_FLAG);
             mGlobalWifiRunning = false;
             mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
             int N = ws.size();
@@ -7082,12 +6524,7 @@
             }
             mWifiSupplState = supplState;
             mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs);
-            mHistoryCur.states2 =
-                    (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
-                    | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
-                    + Integer.toHexString(mHistoryCur.states2));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState);
         }
     }
 
@@ -7116,12 +6553,8 @@
                 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
                     mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
                 }
-                mHistoryCur.states2 =
-                        (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
-                        | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
-                if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
-                        + Integer.toHexString(mHistoryCur.states2));
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs,
+                        strengthBin);
             } else {
                 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs);
             }
@@ -7134,10 +6567,8 @@
     @GuardedBy("this")
     public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mWifiFullLockNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_FULL_LOCK_FLAG);
         }
         mWifiFullLockNesting++;
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -7148,10 +6579,8 @@
     public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         mWifiFullLockNesting--;
         if (mWifiFullLockNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_FULL_LOCK_FLAG);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
                 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs);
@@ -7167,10 +6596,8 @@
     @GuardedBy("this")
     public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         if (mWifiScanNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_SCAN_FLAG);
         }
         mWifiScanNesting++;
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -7186,10 +6613,8 @@
     public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         mWifiScanNesting--;
         if (mWifiScanNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_SCAN_FLAG);
         }
         getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
                 .noteWifiScanStoppedLocked(elapsedRealtimeMs);
@@ -7214,14 +6639,10 @@
     public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
         uid = mapUid(uid);
         if (mWifiMulticastNesting == 0) {
-            mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
-
+            mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG);
             // Start Wifi Multicast overall timer
             if (!mWifiMulticastWakelockTimer.isRunningLocked()) {
-                if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started");
                 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs);
             }
         }
@@ -7235,14 +6656,12 @@
         uid = mapUid(uid);
         mWifiMulticastNesting--;
         if (mWifiMulticastNesting == 0) {
-            mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG);
 
             // Stop Wifi Multicast overall timer
             if (mWifiMulticastWakelockTimer.isRunningLocked()) {
-                if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped");
+                if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped");
                 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
@@ -7994,8 +7413,9 @@
             // If the start clock time has changed by more than a year, then presumably
             // the previous time was completely bogus.  So we are going to figure out a
             // new time based on how much time has elapsed since we started counting.
-            recordCurrentTimeChangeLocked(currentTimeMs, mClock.elapsedRealtime(),
-                    mClock.uptimeMillis());
+            mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                    currentTimeMs
+            );
             return currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000));
         }
         return mStartClockTimeMs;
@@ -11227,18 +10647,19 @@
             UserInfoProvider userInfoProvider) {
         init(clock);
 
+        mHandler = new MyHandler(handler.getLooper());
+        mConstants = new Constants(mHandler);
+
         if (systemDir == null) {
             mStatsFile = null;
-            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
+            mHistory = new BatteryStatsHistory(mStepDetailsCalculator, mClock);
         } else {
             mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin"));
-            mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer, systemDir,
-                    this::getMaxHistoryFiles);
+            mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES,
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock);
         }
         mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
         mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
-        mHandler = new MyHandler(handler.getLooper());
-        mConstants = new Constants(mHandler);
         mStartCount++;
         initTimersAndCounters();
         mOnBattery = mOnBatteryInternal = false;
@@ -11247,7 +10668,6 @@
         initTimes(uptimeUs, realtimeUs);
         mStartPlatformVersion = mEndPlatformVersion = Build.ID;
         initDischarge(realtimeUs);
-        clearHistoryLocked();
         updateDailyDeadlineLocked();
         mPlatformIdleStateCallback = cb;
         mMeasuredEnergyRetriever = energyStatsCb;
@@ -11258,12 +10678,6 @@
         FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode);
     }
 
-    private int getMaxHistoryFiles() {
-        synchronized (this) {
-            return mConstants.MAX_HISTORY_FILES;
-        }
-    }
-
     @VisibleForTesting
     protected void initTimersAndCounters() {
         mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase);
@@ -11345,7 +10759,7 @@
         mDischargeUnplugLevel = 0;
         mDischargePlugLevel = -1;
         mDischargeCurrentLevel = 0;
-        mCurrentBatteryLevel = 0;
+        mBatteryLevel = 0;
     }
 
     public void setPowerProfileLocked(PowerProfile profile) {
@@ -11732,7 +11146,7 @@
     }
 
     public int getHistoryUsedSize() {
-        return mBatteryStatsHistory.getHistoryUsedSize();
+        return mHistory.getHistoryUsedSize();
     }
 
     @Override
@@ -11746,43 +11160,27 @@
      */
     @VisibleForTesting
     public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() {
-        return new BatteryStatsHistoryIterator(mBatteryStatsHistory);
+        return mHistory.iterate();
     }
 
     @Override
     public int getHistoryStringPoolSize() {
-        return mHistoryTagPool.size();
+        return mHistory.getHistoryStringPoolSize();
     }
 
     @Override
     public int getHistoryStringPoolBytes() {
-        return mNumHistoryTagChars;
+        return mHistory.getHistoryStringPoolBytes();
     }
 
     @Override
     public String getHistoryTagPoolString(int index) {
-        ensureHistoryTagArray();
-        HistoryTag historyTag = mHistoryTags.get(index);
-        return historyTag != null ? historyTag.string : null;
+        return mHistory.getHistoryTagPoolString(index);
     }
 
     @Override
     public int getHistoryTagPoolUid(int index) {
-        ensureHistoryTagArray();
-        HistoryTag historyTag = mHistoryTags.get(index);
-        return historyTag != null ? historyTag.uid : Process.INVALID_UID;
-    }
-
-    private void ensureHistoryTagArray() {
-        if (mHistoryTags != null) {
-            return;
-        }
-
-        mHistoryTags = new SparseArray<>(mHistoryTagPool.size());
-        for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) {
-            mHistoryTags.put(entry.getValue() & ~BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG,
-                    entry.getKey());
-        }
+        return mHistory.getHistoryTagPoolUid(index);
     }
 
     @Override
@@ -11792,15 +11190,11 @@
 
     @Override
     public void finishIteratingHistoryLocked() {
+        mBatteryStatsHistoryIterator.close();
         mBatteryStatsHistoryIterator = null;
     }
 
     @Override
-    public long getHistoryBaseTime() {
-        return mHistoryBaseTimeMs;
-    }
-
-    @Override
     public int getStartCount() {
         return mStartCount;
     }
@@ -11853,24 +11247,23 @@
         long realtimeUs = mSecRealtime * 1000;
         resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
         pullPendingStateUpdatesLocked();
-        addHistoryRecordLocked(mSecRealtime, mSecUptime);
-        mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
-                = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
+        mHistory.writeHistoryItem(mSecRealtime, mSecUptime);
+        mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel;
         mOnBatteryTimeBase.reset(uptimeUs, realtimeUs);
         mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs);
-        if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
+        if (!mBatteryPluggedIn) {
             if (Display.isOnState(mScreenState)) {
-                mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
+                mDischargeScreenOnUnplugLevel = mBatteryLevel;
                 mDischargeScreenDozeUnplugLevel = 0;
                 mDischargeScreenOffUnplugLevel = 0;
             } else if (Display.isDozeState(mScreenState)) {
                 mDischargeScreenOnUnplugLevel = 0;
-                mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel;
+                mDischargeScreenDozeUnplugLevel = mBatteryLevel;
                 mDischargeScreenOffUnplugLevel = 0;
             } else {
                 mDischargeScreenOnUnplugLevel = 0;
                 mDischargeScreenDozeUnplugLevel = 0;
-                mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
+                mDischargeScreenOffUnplugLevel = mBatteryLevel;
             }
             mDischargeAmountScreenOn = 0;
             mDischargeAmountScreenOff = 0;
@@ -12014,27 +11407,12 @@
 
         resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs);
 
-        mLastHistoryStepDetails = null;
-        mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0;
-        mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0;
-        mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0;
-        mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0;
-        mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0;
-        mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0;
-        mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0;
-        mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0;
-        mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0;
-        mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0;
-
         mNumAllUidCpuTimeReads = 0;
         mNumUidsRemoved = 0;
 
         initDischarge(elapsedRealtimeUs);
 
-        clearHistoryLocked();
-        if (mBatteryStatsHistory != null) {
-            mBatteryStatsHistory.resetAllFiles();
-        }
+        mHistory.reset();
 
         // Flush external data, gathering snapshots, but don't process it since it is pre-reset data
         mIgnoreNextExternalStats = true;
@@ -12057,7 +11435,7 @@
             for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
                 SparseIntArray uids = ent.getValue();
                 for (int j=0; j<uids.size(); j++) {
-                    addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
+                    mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
                             uids.keyAt(j));
                 }
             }
@@ -12482,9 +11860,8 @@
                         (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt);
                 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
                         monitoredRailChargeConsumedMaMs);
-                mHistoryCur.wifiRailChargeMah +=
-                        (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs,
+                        (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
                 mTmpRailStats.resetWifiTotalEnergyUsed();
 
                 if (uidEstimatedConsumptionMah != null) {
@@ -12597,9 +11974,8 @@
                             (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt);
                     mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
                             monitoredRailChargeConsumedMaMs);
-                    mHistoryCur.modemRailChargeMah +=
-                            (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
-                    addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                    mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs,
+                            (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
                     mTmpRailStats.resetCellularTotalEnergyUsed();
                 }
 
@@ -12867,8 +12243,8 @@
             }
         }
         if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) {
-            mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
-            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+            mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
+                    HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG);
         }
     }
 
@@ -14301,11 +13677,7 @@
         mHandler.removeCallbacks(mDeferSetCharging);
         if (mCharging != charging) {
             mCharging = charging;
-            if (charging) {
-                mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
-            } else {
-                mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
-            }
+            mHistory.setChargingState(charging);
             mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
             return true;
         }
@@ -14319,6 +13691,15 @@
         mSystemReady = true;
     }
 
+    /**
+     * Force recording of all history events regardless of the "charging" state.
+     */
+    @VisibleForTesting
+    public void forceRecordAllHistory() {
+        mHistory.forceRecordAllHistory();
+        mRecordAllHistory = true;
+    }
+
     @GuardedBy("this")
     protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
             final boolean onBattery, final int oldStatus, final int level, final int chargeUah) {
@@ -14402,15 +13783,12 @@
             mInitStepMode = mCurStepMode;
             mModStepMode = 0;
             pullPendingStateUpdatesLocked();
-            mHistoryCur.batteryLevel = (byte)level;
-            mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
-                    + Integer.toHexString(mHistoryCur.states));
             if (reset) {
-                mRecordingHistory = true;
-                startRecordingHistory(mSecRealtime, mSecUptime, reset);
+                mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset);
+                initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
             }
-            addHistoryRecordLocked(mSecRealtime, mSecUptime);
+            mBatteryPluggedIn = false;
+            mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn);
             mDischargeCurrentLevel = mDischargeUnplugLevel = level;
             if (Display.isOnState(screenState)) {
                 mDischargeScreenOnUnplugLevel = level;
@@ -14432,11 +13810,8 @@
         } else {
             mOnBattery = mOnBatteryInternal = false;
             pullPendingStateUpdatesLocked();
-            mHistoryCur.batteryLevel = (byte)level;
-            mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
-            if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(mSecRealtime, mSecUptime);
+            mBatteryPluggedIn = true;
+            mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn);
             mDischargeCurrentLevel = mDischargePlugLevel = level;
             if (level < mDischargeUnplugLevel) {
                 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
@@ -14451,45 +13826,12 @@
             mModStepMode = 0;
         }
         if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) {
-            if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) {
+            if (mStatsFile != null && !mHistory.isReadOnly()) {
                 writeAsyncLocked();
             }
         }
     }
 
-    @GuardedBy("this")
-    private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
-            boolean reset) {
-        mRecordingHistory = true;
-        mHistoryCur.currentTime = mClock.currentTimeMillis();
-        addHistoryBufferLocked(elapsedRealtimeMs,
-                reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
-                mHistoryCur);
-        mHistoryCur.currentTime = 0;
-        if (reset) {
-            initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
-        }
-    }
-
-    @GuardedBy("this")
-    private void recordCurrentTimeChangeLocked(final long currentTimeMs,
-            final long elapsedRealtimeMs, final long uptimeMs) {
-        if (mRecordingHistory) {
-            mHistoryCur.currentTime = currentTimeMs;
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur);
-            mHistoryCur.currentTime = 0;
-        }
-    }
-
-    @GuardedBy("this")
-    private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) {
-        if (mRecordingHistory) {
-            mHistoryCur.currentTime = currentTimeMs;
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur);
-            mHistoryCur.currentTime = 0;
-        }
-    }
-
     private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) {
         if (mExternalSync != null) {
             mExternalSync.scheduleSync(reason, updateFlags);
@@ -14507,8 +13849,7 @@
         // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
         temp = Math.max(0, temp);
 
-        reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
-                status, plugType, level);
+        reportChangesToStatsLog(status, plugType, level);
 
         final boolean onBattery = isOnBattery(plugType, status);
         if (!mHaveBatteryLevel) {
@@ -14518,52 +13859,47 @@
             // plugged in, then twiddle our state to correctly reflect that
             // since we won't be going through the full setOnBattery().
             if (onBattery == mOnBattery) {
-                if (onBattery) {
-                    mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
-                } else {
-                    mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
-                }
+                mHistory.setPluggedInState(!onBattery);
             }
+            mBatteryStatus = status;
+            mBatteryLevel = level;
+            mBatteryChargeUah = chargeUah;
+
             // Always start out assuming charging, that will be updated later.
-            mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
-            mHistoryCur.batteryStatus = (byte)status;
-            mHistoryCur.batteryLevel = (byte)level;
-            mHistoryCur.batteryChargeUah = chargeUah;
+            mHistory.setBatteryState(true /* charging */, status, level, chargeUah);
+
             mMaxChargeStepLevel = mMinDischargeStepLevel =
                     mLastChargeStepLevel = mLastDischargeStepLevel = level;
-        } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
+        } else if (mBatteryLevel != level || mOnBattery != onBattery) {
             recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs);
         }
-        int oldStatus = mHistoryCur.batteryStatus;
+        int oldStatus = mBatteryStatus;
         if (onBattery) {
             mDischargeCurrentLevel = level;
-            if (!mRecordingHistory) {
-                mRecordingHistory = true;
-                startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
+            if (!mHistory.isRecordingHistory()) {
+                mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
             }
         } else if (level < 96 &&
                 status != BatteryManager.BATTERY_STATUS_UNKNOWN) {
-            if (!mRecordingHistory) {
-                mRecordingHistory = true;
-                startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
+            if (!mHistory.isRecordingHistory()) {
+                mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
             }
         }
-        mBatteryVoltageMv = voltageMv;
-        mCurrentBatteryLevel = level;
         if (mDischargePlugLevel < 0) {
             mDischargePlugLevel = level;
         }
 
         if (onBattery != mOnBattery) {
-            mHistoryCur.batteryLevel = (byte)level;
-            mHistoryCur.batteryStatus = (byte)status;
-            mHistoryCur.batteryHealth = (byte)health;
-            mHistoryCur.batteryPlugType = (byte)plugType;
-            mHistoryCur.batteryTemperature = (short)temp;
-            mHistoryCur.batteryVoltage = (char) voltageMv;
-            if (chargeUah < mHistoryCur.batteryChargeUah) {
+            mBatteryLevel = level;
+            mBatteryStatus = status;
+            mBatteryHealth = health;
+            mBatteryPlugType = plugType;
+            mBatteryTemperature = temp;
+            mBatteryVoltageMv = voltageMv;
+            mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah);
+            if (chargeUah < mBatteryChargeUah) {
                 // Only record discharges
-                final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah;
+                final long chargeDiff = (long) mBatteryChargeUah - chargeUah;
                 mDischargeCounter.addCountLocked(chargeDiff);
                 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
                 if (Display.isDozeState(mScreenState)) {
@@ -14575,12 +13911,12 @@
                     mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
                 }
             }
-            mHistoryCur.batteryChargeUah = chargeUah;
+            mBatteryChargeUah = chargeUah;
             setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah);
         } else {
             boolean changed = false;
-            if (mHistoryCur.batteryLevel != level) {
-                mHistoryCur.batteryLevel = (byte)level;
+            if (mBatteryLevel != level) {
+                mBatteryLevel = level;
                 changed = true;
 
                 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
@@ -14588,33 +13924,33 @@
                 mExternalSync.scheduleSyncDueToBatteryLevelChange(
                         mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS);
             }
-            if (mHistoryCur.batteryStatus != status) {
-                mHistoryCur.batteryStatus = (byte)status;
+            if (mBatteryStatus != status) {
+                mBatteryStatus = status;
                 changed = true;
             }
-            if (mHistoryCur.batteryHealth != health) {
-                mHistoryCur.batteryHealth = (byte)health;
+            if (mBatteryHealth != health) {
+                mBatteryHealth = health;
                 changed = true;
             }
-            if (mHistoryCur.batteryPlugType != plugType) {
-                mHistoryCur.batteryPlugType = (byte)plugType;
+            if (mBatteryPlugType != plugType) {
+                mBatteryPlugType = plugType;
                 changed = true;
             }
-            if (temp >= (mHistoryCur.batteryTemperature+10)
-                    || temp <= (mHistoryCur.batteryTemperature-10)) {
-                mHistoryCur.batteryTemperature = (short)temp;
+            if (temp >= (mBatteryTemperature + 10)
+                    || temp <= (mBatteryTemperature - 10)) {
+                mBatteryTemperature = temp;
                 changed = true;
             }
-            if (voltageMv > (mHistoryCur.batteryVoltage + 20)
-                    || voltageMv < (mHistoryCur.batteryVoltage - 20)) {
-                mHistoryCur.batteryVoltage = (char) voltageMv;
+            if (voltageMv > (mBatteryVoltageMv + 20)
+                    || voltageMv < (mBatteryVoltageMv - 20)) {
+                mBatteryVoltageMv = voltageMv;
                 changed = true;
             }
-            if (chargeUah >= (mHistoryCur.batteryChargeUah + 10)
-                    || chargeUah <= (mHistoryCur.batteryChargeUah - 10)) {
-                if (chargeUah < mHistoryCur.batteryChargeUah) {
+            if (chargeUah >= (mBatteryChargeUah + 10)
+                    || chargeUah <= (mBatteryChargeUah - 10)) {
+                if (chargeUah < mBatteryChargeUah) {
                     // Only record discharges
-                    final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah;
+                    final long chargeDiff = (long) mBatteryChargeUah - chargeUah;
                     mDischargeCounter.addCountLocked(chargeDiff);
                     mDischargeScreenOffCounter.addCountLocked(chargeDiff);
                     if (Display.isDozeState(mScreenState)) {
@@ -14626,9 +13962,10 @@
                         mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
                     }
                 }
-                mHistoryCur.batteryChargeUah = chargeUah;
+                mBatteryChargeUah = chargeUah;
                 changed = true;
             }
+
             long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
                     | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
                     | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
@@ -14686,7 +14023,10 @@
                 mLastChargeStepLevel = level;
             }
             if (changed) {
-                addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+                mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth,
+                        mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv,
+                        mBatteryChargeUah);
+                mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs);
             }
         }
         if (!onBattery &&
@@ -14695,7 +14035,7 @@
             // We don't record history while we are plugged in and fully charged
             // (or when battery is not present).  The next time we are
             // unplugged, history will be cleared.
-            mRecordingHistory = DEBUG;
+            mHistory.setHistoryRecordingEnabled(DEBUG);
         }
 
         mLastLearnedBatteryCapacityUah = chargeFullUah;
@@ -14714,17 +14054,18 @@
     }
 
     // Inform StatsLog of setBatteryState changes.
-    // If this is the first reporting, pass in recentPast == null.
-    private void reportChangesToStatsLog(HistoryItem recentPast,
-            final int status, final int plugType, final int level) {
+    private void reportChangesToStatsLog(final int status, final int plugType, final int level) {
+        if (!mHaveBatteryLevel) {
+            return;
+        }
 
-        if (recentPast == null || recentPast.batteryStatus != status) {
+        if (mBatteryStatus != status) {
             FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status);
         }
-        if (recentPast == null || recentPast.batteryPlugType != plugType) {
+        if (mBatteryPlugType != plugType) {
             FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType);
         }
-        if (recentPast == null || recentPast.batteryLevel != level) {
+        if (mBatteryLevel != level) {
             FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level);
         }
     }
@@ -14794,7 +14135,7 @@
         if (msPerLevel <= 0) {
             return -1;
         }
-        return (msPerLevel * mCurrentBatteryLevel) * 1000;
+        return (msPerLevel * mBatteryLevel) * 1000;
     }
 
     @Override
@@ -14824,7 +14165,7 @@
         if (msPerLevel <= 0) {
             return -1;
         }
-        return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000;
+        return (msPerLevel * (100 - mBatteryLevel)) * 1000;
     }
 
     /*@hide */
@@ -15255,7 +14596,8 @@
 
     @GuardedBy("this")
     public void shutdownLocked() {
-        recordShutdownLocked(mClock.currentTimeMillis(), mClock.elapsedRealtime());
+        mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                mClock.currentTimeMillis());
         writeSyncLocked();
         mShuttingDown = true;
     }
@@ -15463,7 +14805,6 @@
                 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong(
                         KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS,
                         DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS);
-
                 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES,
                         ActivityManager.isLowRamDeviceStatic() ?
                                 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE
@@ -15474,9 +14815,20 @@
                                 : DEFAULT_MAX_HISTORY_BUFFER_KB)
                         * 1024;
                 updateBatteryChargedDelayMsLocked();
+
+                onChange();
             }
         }
 
+        /**
+         * Propagates changes in constant values.
+         */
+        @VisibleForTesting
+        public void onChange() {
+            mHistory.setMaxHistoryFiles(MAX_HISTORY_FILES);
+            mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER);
+        }
+
         private void updateBatteryChargedDelayMsLocked() {
             // a negative value indicates that we should ignore this override
             final int delay = Settings.Global.getInt(mResolver,
@@ -15697,27 +15049,11 @@
     }
 
     private void writeHistoryLocked() {
-        if (mBatteryStatsHistory.getActiveFile() == null) {
-            Slog.w(TAG, "writeHistoryLocked: no history file associated with this instance");
-            return;
-        }
-
         if (mShuttingDown) {
             return;
         }
 
-        Parcel p = Parcel.obtain();
-        try {
-            final long start = SystemClock.uptimeMillis();
-            writeHistoryBuffer(p, true);
-            if (DEBUG) {
-                Slog.d(TAG, "writeHistoryBuffer duration ms:"
-                        + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize());
-            }
-            writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile());
-        } finally {
-            p.recycle();
-        }
+        mHistory.writeHistory();
     }
 
     private final ReentrantLock mWriteLock = new ReentrantLock();
@@ -15756,13 +15092,6 @@
             return;
         }
 
-        final AtomicFile activeHistoryFile = mBatteryStatsHistory.getActiveFile();
-        if (activeHistoryFile == null) {
-            Slog.w(TAG,
-                    "readLocked: no history file associated with this instance");
-            return;
-        }
-
         mUidStats.clear();
 
         Parcel stats = Parcel.obtain();
@@ -15775,7 +15104,7 @@
                 readSummaryFromParcel(stats);
                 if (DEBUG) {
                     Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath()
-                            + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis()
+                            + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis()
                             - start));
                 }
             }
@@ -15787,126 +15116,19 @@
             stats.recycle();
         }
 
-        Parcel history = Parcel.obtain();
-        try {
-            final long start = SystemClock.uptimeMillis();
-            if (activeHistoryFile.exists()) {
-                byte[] raw = activeHistoryFile.readFully();
-                if (raw.length > 0) {
-                    history.unmarshall(raw, 0, raw.length);
-                    history.setDataPosition(0);
-                    readHistoryBuffer(history);
-                }
-                if (DEBUG) {
-                    Slog.d(TAG, "readLocked history file::"
-                            + activeHistoryFile.getBaseFile().getPath()
-                            + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis()
-                            - start));
-                }
-            }
-        } catch (Exception e) {
-            Slog.e(TAG, "Error reading battery history", e);
-            clearHistoryLocked();
-            mBatteryStatsHistory.resetAllFiles();
-        } finally {
-            history.recycle();
+        if (!mHistory.readSummary()) {
+            resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(),
+                    RESET_REASON_CORRUPT_FILE);
         }
 
         mEndPlatformVersion = Build.ID;
 
-        if (mHistoryBuffer.dataPosition() > 0
-                || mBatteryStatsHistory.getFilesNumbers().size() > 1) {
-            mRecordingHistory = true;
-            final long elapsedRealtimeMs = mClock.elapsedRealtime();
-            final long uptimeMs = mClock.uptimeMillis();
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur);
-            startRecordingHistory(elapsedRealtimeMs, uptimeMs, false);
-        }
+        mHistory.continueRecordingHistory();
 
         recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis());
     }
 
     @GuardedBy("this")
-    void  readHistoryBuffer(Parcel in) throws ParcelFormatException {
-        final int version = in.readInt();
-        if (version != BatteryStatsHistory.VERSION) {
-            Slog.w("BatteryStats", "readHistoryBuffer: version got " + version
-                    + ", expected " + BatteryStatsHistory.VERSION + "; erasing old stats");
-            return;
-        }
-
-        final long historyBaseTime = in.readLong();
-
-        mHistoryBuffer.setDataSize(0);
-        mHistoryBuffer.setDataPosition(0);
-
-        int bufSize = in.readInt();
-        int curPos = in.dataPosition();
-        if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) {
-            throw new ParcelFormatException("File corrupt: history data buffer too large " +
-                    bufSize);
-        } else if ((bufSize&~3) != bufSize) {
-            throw new ParcelFormatException("File corrupt: history data buffer not aligned " +
-                    bufSize);
-        } else {
-            if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
-                    + " bytes at " + curPos);
-            mHistoryBuffer.appendFrom(in, curPos, bufSize);
-            in.setDataPosition(curPos + bufSize);
-        }
-
-        if (DEBUG_HISTORY) {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("****************** OLD mHistoryBaseTimeMs: ");
-            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
-            Slog.i(TAG, sb.toString());
-        }
-        mHistoryBaseTimeMs = historyBaseTime;
-        if (DEBUG_HISTORY) {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("****************** NEW mHistoryBaseTimeMs: ");
-            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
-            Slog.i(TAG, sb.toString());
-        }
-
-        // We are just arbitrarily going to insert 1 minute from the sample of
-        // the last run until samples in this run.
-        if (mHistoryBaseTimeMs > 0) {
-            long oldnow = mClock.elapsedRealtime();
-            mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1;
-            if (DEBUG_HISTORY) {
-                StringBuilder sb = new StringBuilder(128);
-                sb.append("****************** ADJUSTED mHistoryBaseTimeMs: ");
-                TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
-                Slog.i(TAG, sb.toString());
-            }
-        }
-    }
-
-    void writeHistoryBuffer(Parcel out, boolean inclData) {
-        if (DEBUG_HISTORY) {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("****************** WRITING mHistoryBaseTimeMs: ");
-            TimeUtils.formatDuration(mHistoryBaseTimeMs, sb);
-            sb.append(" mLastHistoryElapsedRealtimeMs: ");
-            TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb);
-            Slog.i(TAG, sb.toString());
-        }
-        out.writeInt(BatteryStatsHistory.VERSION);
-        out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs);
-        if (!inclData) {
-            out.writeInt(0);
-            out.writeInt(0);
-            return;
-        }
-
-        out.writeInt(mHistoryBuffer.dataSize());
-        if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
-                + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
-        out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
-    }
-
-    @GuardedBy("this")
     public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
         final int version = in.readInt();
 
@@ -15916,31 +15138,7 @@
             return;
         }
 
-        boolean inclHistory = in.readBoolean();
-        if (inclHistory) {
-            readHistoryBuffer(in);
-            mBatteryStatsHistory.readFromParcel(in);
-        }
-
-        mHistoryTagPool.clear();
-        mNextHistoryTagIdx = 0;
-        mNumHistoryTagChars = 0;
-
-        int numTags = in.readInt();
-        for (int i=0; i<numTags; i++) {
-            int idx = in.readInt();
-            String str = in.readString();
-            int uid = in.readInt();
-            HistoryTag tag = new HistoryTag();
-            tag.string = str;
-            tag.uid = uid;
-            tag.poolIdx = idx;
-            mHistoryTagPool.put(tag, idx);
-            if (idx >= mNextHistoryTagIdx) {
-                mNextHistoryTagIdx = idx+1;
-            }
-            mNumHistoryTagChars += tag.string.length() + 1;
-        }
+        mHistory.readSummaryFromParcel(in);
 
         mStartCount = in.readInt();
         mUptimeUs = in.readLong();
@@ -15953,7 +15151,7 @@
         mDischargeUnplugLevel = in.readInt();
         mDischargePlugLevel = in.readInt();
         mDischargeCurrentLevel = in.readInt();
-        mCurrentBatteryLevel = in.readInt();
+        mBatteryLevel = in.readInt();
         mEstimatedBatteryCapacityMah = in.readInt();
         mLastLearnedBatteryCapacityUah = in.readInt();
         mMinLearnedBatteryCapacityUah = in.readInt();
@@ -16456,19 +15654,7 @@
 
         out.writeInt(VERSION);
 
-        out.writeBoolean(inclHistory);
-        if (inclHistory) {
-            writeHistoryBuffer(out, true);
-            mBatteryStatsHistory.writeToParcel(out);
-        }
-
-        out.writeInt(mHistoryTagPool.size());
-        for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
-            HistoryTag tag = ent.getKey();
-            out.writeInt(ent.getValue());
-            out.writeString(tag.string);
-            out.writeInt(tag.uid);
-        }
+        mHistory.writeSummaryToParcel(out, inclHistory);
 
         out.writeInt(mStartCount);
         out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED));
@@ -16481,7 +15667,7 @@
         out.writeInt(mDischargeUnplugLevel);
         out.writeInt(mDischargePlugLevel);
         out.writeInt(mDischargeCurrentLevel);
-        out.writeInt(mCurrentBatteryLevel);
+        out.writeInt(mBatteryLevel);
         out.writeInt(mEstimatedBatteryCapacityMah);
         out.writeInt(mLastLearnedBatteryCapacityUah);
         out.writeInt(mMinLearnedBatteryCapacityUah);
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index 0cdd4d1..c36d950 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -22,7 +22,6 @@
 import android.os.BatteryStats;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
-import android.os.Parcel;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UidBatteryConsumer;
@@ -32,10 +31,8 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.BatteryStatsHistory;
 import com.android.internal.os.PowerProfile;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -220,18 +217,7 @@
             }
 
             BatteryStatsImpl batteryStatsImpl = (BatteryStatsImpl) mStats;
-
-            // Make a copy of battery history to avoid concurrent modification.
-            Parcel historyBuffer = Parcel.obtain();
-            historyBuffer.appendFrom(batteryStatsImpl.mHistoryBuffer, 0,
-                    batteryStatsImpl.mHistoryBuffer.dataSize());
-
-            final File systemDir =
-                    batteryStatsImpl.mBatteryStatsHistory.getHistoryDirectory().getParentFile();
-            final BatteryStatsHistory batteryStatsHistory =
-                    new BatteryStatsHistory(historyBuffer, systemDir, null);
-
-            batteryUsageStatsBuilder.setBatteryHistory(batteryStatsHistory);
+            batteryUsageStatsBuilder.setBatteryHistory(batteryStatsImpl.copyHistory());
         }
 
         BatteryUsageStats stats = batteryUsageStatsBuilder.build();
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index 61a7f38..5c934852 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -28,6 +28,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.os.BatteryStatsHistory;
+import com.android.internal.os.Clock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,13 +50,14 @@
     private final Parcel mHistoryBuffer = Parcel.obtain();
     private File mSystemDir;
     private File mHistoryDir;
+    private final Clock mClock = new MockClock();
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         Context context = InstrumentationRegistry.getContext();
         mSystemDir = context.getDataDir();
-        mHistoryDir = new File(mSystemDir, BatteryStatsHistory.HISTORY_DIR);
+        mHistoryDir = new File(mSystemDir, "battery-history");
         String[] files = mHistoryDir.list();
         if (files != null) {
             for (int i = 0; i < files.length; i++) {
@@ -67,8 +69,8 @@
 
     @Test
     public void testConstruct() {
-        BatteryStatsHistory history =
-                new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
+        BatteryStatsHistory history = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
+                null, mClock);
         createActiveFile(history);
         verifyFileNumbers(history, Arrays.asList(0));
         verifyActiveFile(history, "0.bin");
@@ -76,8 +78,8 @@
 
     @Test
     public void testStartNextFile() {
-        BatteryStatsHistory history =
-                new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
+        BatteryStatsHistory history = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
+                null, mClock);
         List<Integer> fileList = new ArrayList<>();
         fileList.add(0);
         createActiveFile(history);
@@ -114,13 +116,13 @@
         assertEquals(0, history.getHistoryUsedSize());
 
         // create a new BatteryStatsHistory object, it will pick up existing history files.
-        BatteryStatsHistory history2 =
-                new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
-        // verify construct can pick up all files from file system.
+        BatteryStatsHistory history2 = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
+                null, mClock);
+        // verify constructor can pick up all files from file system.
         verifyFileNumbers(history2, fileList);
         verifyActiveFile(history2, "33.bin");
 
-        history2.resetAllFiles();
+        history2.reset();
         createActiveFile(history2);
         // verify all existing files are deleted.
         for (int i = 2; i < 33; ++i) {
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index 713e786..570b2ee 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
@@ -63,6 +63,7 @@
     MockBatteryStatsImpl(Clock clock, File historyDirectory) {
         super(clock, historyDirectory);
         initTimersAndCounters();
+        setMaxHistoryBuffer(128 * 1024);
 
         setExternalStatsSyncLocked(mExternalStatsSync);
         informThatAllExternalStatsAreFlushed();
@@ -104,12 +105,6 @@
         return mForceOnBattery ? true : super.isOnBattery();
     }
 
-    public void forceRecordAllHistory() {
-        mHaveBatteryLevel = true;
-        mRecordingHistory = true;
-        mRecordAllHistory = true;
-    }
-
     public TimeBase getOnBatteryBackgroundTimeBase(int uid) {
         return getUidStatsLocked(uid).mOnBatteryBackgroundTimeBase;
     }
@@ -201,12 +196,14 @@
     @GuardedBy("this")
     public MockBatteryStatsImpl setMaxHistoryFiles(int maxHistoryFiles) {
         mConstants.MAX_HISTORY_FILES = maxHistoryFiles;
+        mConstants.onChange();
         return this;
     }
 
     @GuardedBy("this")
     public MockBatteryStatsImpl setMaxHistoryBuffer(int maxHistoryBuffer) {
         mConstants.MAX_HISTORY_BUFFER = maxHistoryBuffer;
+        mConstants.onChange();
         return this;
     }
 
