Revert "Breaking history writing out of BatteryStatsImpl"
This reverts commit 62242bdca32c0b519ad11b035b990f17e9974a3f.
Reason for revert: ramdumps on ToT related to battersystats parcel parsing
Bug: 243434675
Change-Id: I18522929f5a1499f56a0cc19606c28a2ed9fc26d
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index da20626..09a52e4 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2326,6 +2326,11 @@
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();
@@ -7610,6 +7615,8 @@
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 6909965..962870e 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -17,35 +17,25 @@
package com.android.internal.os;
import android.annotation.Nullable;
-import android.os.BatteryManager;
-import android.os.BatteryStats.HistoryItem;
-import android.os.BatteryStats.HistoryStepDetails;
-import android.os.BatteryStats.HistoryTag;
+import android.os.BatteryStats;
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.concurrent.locks.ReentrantLock;
+import java.util.function.Supplier;
/**
* BatteryStatsHistory encapsulates battery history files.
@@ -66,62 +56,57 @@
* 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
- private static final int VERSION = 208;
+ public static final int VERSION = 208;
- private static final String HISTORY_DIR = "battery-history";
- private static final String FILE_SUFFIX = ".bin";
+ public static final String HISTORY_DIR = "battery-history";
+ public 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.
- 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.
+ 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.
// Flag in delta int: a new battery level int follows.
- static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
+ public static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
// Flag in delta int: a new full state and battery status int follows.
- static final int DELTA_STATE_FLAG = 0x00100000;
+ public static final int DELTA_STATE_FLAG = 0x00100000;
// Flag in delta int: a new full state2 int follows.
- static final int DELTA_STATE2_FLAG = 0x00200000;
+ public static final int DELTA_STATE2_FLAG = 0x00200000;
// Flag in delta int: contains a wakelock or wakeReason tag.
- static final int DELTA_WAKELOCK_FLAG = 0x00400000;
+ public static final int DELTA_WAKELOCK_FLAG = 0x00400000;
// Flag in delta int: contains an event description.
- static final int DELTA_EVENT_FLAG = 0x00800000;
+ public static final int DELTA_EVENT_FLAG = 0x00800000;
// Flag in delta int: contains the battery charge count in uAh.
- static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
+ public static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
// These upper bits are the frequently changing state bits.
- static final int DELTA_STATE_MASK = 0xfe000000;
+ public 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.
- 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;
+ 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;
// We use the low bit of the battery state int to indicate that we have full details
// from a battery level change.
- static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
+ public 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
- static final int TAG_FIRST_OCCURRENCE_FLAG = 0x8000;
+ public 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.
*/
@@ -159,77 +144,19 @@
*/
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 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
+ * @param historyBuffer The in-memory history buffer.
+ * @param systemDir typically /data/system
+ * @param maxHistoryFiles the largest number of history buffer files to keep
*/
- 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) {
+ Supplier<Integer> maxHistoryFiles) {
mHistoryBuffer = historyBuffer;
- mSystemDir = systemDir;
- mMaxHistoryFiles = maxHistoryFiles;
- mMaxHistoryBufferSize = maxHistoryBufferSize;
- mStepDetailsCalculator = stepDetailsCalculator;
- mClock = clock;
-
mHistoryDir = new File(systemDir, HISTORY_DIR);
+ mMaxHistoryFiles = maxHistoryFiles;
+
mHistoryDir.mkdirs();
if (!mHistoryDir.exists()) {
Slog.wtf(TAG, "HistoryDir does not exist:" + mHistoryDir.getPath());
@@ -265,81 +192,19 @@
}
}
- public BatteryStatsHistory(HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
- mStepDetailsCalculator = stepDetailsCalculator;
- mClock = clock;
-
- mHistoryBuffer = Parcel.obtain();
- mSystemDir = null;
- mHistoryDir = null;
- initHistoryBuffer();
- }
-
/**
* Used when BatteryStatsImpl object is created from deserialization of a parcel,
- * such as a checkin file.
+ * such as Settings app or checkin file.
+ * @param historyBuffer the history buffer
*/
- private BatteryStatsHistory(Parcel historyBuffer,
- HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock) {
- mHistoryBuffer = historyBuffer;
- mClock = clock;
- mSystemDir = null;
+ public BatteryStatsHistory(Parcel historyBuffer) {
mHistoryDir = null;
- mStepDetailsCalculator = stepDetailsCalculator;
+ mHistoryBuffer = historyBuffer;
+ mMaxHistoryFiles = null;
}
- 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;
+ public File getHistoryDirectory() {
+ return mHistoryDir;
}
/**
@@ -356,13 +221,12 @@
/**
* 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));
}
/**
@@ -370,7 +234,7 @@
* create next history file.
*/
public void startNextFile() {
- if (mMaxHistoryFiles == 0) {
+ if (mMaxHistoryFiles == null) {
Slog.wtf(TAG, "mMaxHistoryFiles should not be zero when writing history");
return;
}
@@ -400,7 +264,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) {
+ while (mFileNumbers.size() > mMaxHistoryFiles.get()) {
int oldest = mFileNumbers.get(0);
getFile(oldest).delete();
mFileNumbers.remove(0);
@@ -408,43 +272,36 @@
}
/**
- * Clear history buffer and delete all existing history files. Active history file start from
- * number 0 again.
+ * Delete all existing history files. Active history file start from number 0 again.
*/
- public void reset() {
- if (DEBUG) Slog.i(TAG, "********** CLEARING HISTORY!");
+ public void resetAllFiles() {
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 BatteryStatsHistoryIterator iterate() {
+ public boolean startIteratingHistory() {
mRecordCount = 0;
mCurrentFileIndex = 0;
mCurrentParcel = null;
mCurrentParcelEnd = 0;
mParcelIndex = 0;
- mBatteryStatsHistoryIterator = new BatteryStatsHistoryIterator(this);
- return mBatteryStatsHistoryIterator;
+ return true;
}
/**
* Finish iterating history files and history buffer.
*/
- void finishIteratingHistory() {
+ public 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);
}
@@ -454,12 +311,11 @@
* 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(HistoryItem out) {
+ public Parcel getNextParcel(BatteryStats.HistoryItem out) {
if (mRecordCount == 0) {
// reset out if it is the first record.
out.clear();
@@ -467,7 +323,8 @@
++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;
@@ -532,8 +389,7 @@
/**
* 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.
*/
@@ -546,8 +402,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);
@@ -557,7 +413,6 @@
/**
* Skip the header part of history parcel.
- *
* @param p history parcel to skip head.
* @return true if version match, false if not.
*/
@@ -573,68 +428,18 @@
}
/**
- * 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) {
@@ -645,13 +450,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);
@@ -675,55 +480,17 @@
Parcel historyBuffer = Parcel.obtain();
historyBuffer.unmarshall(historyBlob, 0, historyBlob.length);
- BatteryStatsHistory history = new BatteryStatsHistory(historyBuffer, null,
- Clock.SYSTEM_CLOCK);
+ BatteryStatsHistory history = new BatteryStatsHistory(historyBuffer);
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 */);
}
@@ -731,7 +498,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;
@@ -754,12 +521,10 @@
return stats.getAvailableBytes() > MIN_FREE_SPACE;
}
- @VisibleForTesting
public List<Integer> getFilesNumbers() {
return mFileNumbers;
}
- @VisibleForTesting
public AtomicFile getActiveFile() {
return mActiveFile;
}
@@ -769,972 +534,15 @@
*/
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 1bf878cb..de8b414 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java
@@ -36,6 +36,7 @@
public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history) {
mBatteryStatsHistory = history;
+ mBatteryStatsHistory.startIteratingHistory();
}
/**
@@ -230,11 +231,4 @@
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 df902c2..fe4aa53 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.recordHistoryEventLocked(
+ mStats.addHistoryEventLocked(
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 968f916..0c9ada8 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -108,7 +108,6 @@
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;
@@ -174,6 +173,7 @@
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,11 +322,6 @@
@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;
@@ -418,7 +413,7 @@
if (changed) {
final long uptimeMs = mClock.uptimeMillis();
final long elapsedRealtimeMs = mClock.elapsedRealtime();
- mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
}
@@ -673,16 +668,16 @@
/**
* Mapping isolated uids to the actual owning app uid.
*/
- private final SparseIntArray mIsolatedUids = new SparseIntArray();
+ final SparseIntArray mIsolatedUids = new SparseIntArray();
/**
* Internal reference count of isolated uids.
*/
- private final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
+ final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
/**
* The statistics we have collected organized by uids.
*/
- private final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
+ 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.
@@ -690,21 +685,20 @@
// changes.
@VisibleForTesting
protected ArrayList<StopwatchTimer> mPartialTimers = 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<>();
+ 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<>();
// Last partial timers we use for distributing CPU usage.
@VisibleForTesting
@@ -719,24 +713,69 @@
protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true);
private boolean mSystemReady;
- private boolean mShuttingDown;
+ boolean mShuttingDown;
- private final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
- private final HistoryStepDetailsCalculatorImpl mStepDetailsCalculator =
- new HistoryStepDetailsCalculatorImpl();
+ final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
- 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;
+ 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;
@NonNull
- private final BatteryStatsHistory mHistory;
+ 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 BatteryStatsHistoryIterator mBatteryStatsHistoryIterator;
@@ -1352,6 +1391,7 @@
int mDischargeUnplugLevel;
int mDischargePlugLevel;
int mDischargeCurrentLevel;
+ int mCurrentBatteryLevel;
int mLowDischargeAmountSinceCharge;
int mHighDischargeAmountSinceCharge;
int mDischargeScreenOnUnplugLevel;
@@ -1403,6 +1443,7 @@
private int mNumConnectivityChange;
+ private int mBatteryVoltageMv = -1;
private int mEstimatedBatteryCapacityMah = -1;
private int mLastLearnedBatteryCapacityUah = -1;
@@ -1586,27 +1627,28 @@
}
public BatteryStatsImpl(Clock clock) {
- this(clock, null);
+ this(clock, (File) 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;
- mHistory = new BatteryStatsHistory(mStepDetailsCalculator, mClock);
+ mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
} else {
mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
- mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES,
- mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock);
+ mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer, historyDirectory,
+ this::getMaxHistoryFiles);
}
+ mHandler = null;
mPlatformIdleStateCallback = null;
mMeasuredEnergyRetriever = null;
mUserInfoProvider = null;
+ mConstants = new Constants(mHandler);
+ clearHistoryLocked();
}
private void init(Clock clock) {
@@ -3869,188 +3911,406 @@
return kmt;
}
- private class HistoryStepDetailsCalculatorImpl implements HistoryStepDetailsCalculator {
- private final HistoryStepDetails mDetails = new HistoryStepDetails();
+ /**
+ * 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 boolean mHasHistoryStepDetails;
+ 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 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;
+ 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++;
- // Perform a CPU update right after we do this collection, so we have started
- // collecting good data for the next step.
- requestImmediateCpuUpdate();
+ 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;
+ }
+ }
+ /*
+ 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) {
- mDetails.statSubsystemPowerState =
+ mCurHistoryStepDetails.statSubsystemPowerState =
mPlatformIdleStateCallback.getSubsystemLowPowerStats();
if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
- mDetails.statSubsystemPowerState);
- }
+ mCurHistoryStepDetails.statSubsystemPowerState);
- 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();
+ }
+ 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 {
- 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.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;
}
- 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;
}
-
- 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;
- }
+ mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs;
+ mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs;
+ mLastStepStatUserTimeMs = mCurStepStatUserTimeMs;
+ mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs;
+ mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs;
+ mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs;
+ mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs;
+ mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs;
}
@GuardedBy("this")
@Override
public void commitCurrentHistoryBatchLocked() {
- mHistory.commitCurrentHistoryBatchLocked();
+ mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
}
@GuardedBy("this")
@@ -4066,9 +4326,191 @@
}
@GuardedBy("this")
- public void recordHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
+ 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,
String name, int uid) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, 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;
}
@GuardedBy("this")
@@ -4221,13 +4663,13 @@
if (!mActiveEvents.updateState(code, name, uid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, code, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid);
}
@GuardedBy("this")
public void noteCurrentTimeChangedLocked(long currentTimeMs,
long elapsedRealtimeMs, long uptimeMs) {
- mHistory.recordCurrentTimeChange(elapsedRealtimeMs, uptimeMs, currentTimeMs);
+ recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs);
}
@GuardedBy("this")
@@ -4244,7 +4686,7 @@
if (!mRecordAllHistory) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid);
}
@GuardedBy("this")
@@ -4302,7 +4744,8 @@
if (!mRecordAllHistory) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH,
+ name, uid);
}
@GuardedBy("this")
@@ -4318,7 +4761,7 @@
if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid);
}
@GuardedBy("this")
@@ -4334,7 +4777,8 @@
if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH,
+ name, uid);
}
@GuardedBy("this")
@@ -4350,7 +4794,7 @@
if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid);
}
@GuardedBy("this")
@@ -4368,7 +4812,7 @@
if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid);
}
@GuardedBy("this")
@@ -4416,7 +4860,7 @@
for (int i = 0; i < workSource.size(); ++i) {
uid = mapUid(workSource.getUid(i));
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
@@ -4425,7 +4869,7 @@
for (int i = 0; i < workChains.size(); ++i) {
uid = mapUid(workChains.get(i).getAttributionUid());
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
}
@@ -4433,7 +4877,7 @@
uid = mapUid(uid);
if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid);
}
}
}
@@ -4508,7 +4952,7 @@
for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
SparseIntArray uids = ent.getValue();
for (int j=0; j<uids.size(); j++) {
- mHistory.recordEvent(mSecRealtime, mSecUptime,
+ addHistoryEventLocked(mSecRealtime, mSecUptime,
HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
}
}
@@ -4523,8 +4967,8 @@
for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
SparseIntArray uids = ent.getValue();
for (int j=0; j<uids.size(); j++) {
- mHistory.recordEvent(mSecRealtime, mSecUptime, HistoryItem.EVENT_PROC_START,
- ent.getKey(), uids.keyAt(j));
+ addHistoryEventLocked(mSecRealtime, mSecUptime,
+ HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
}
}
}
@@ -4567,19 +5011,30 @@
if (mRecordAllHistory) {
if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
mappedUid, 0)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs,
+ addHistoryEventLocked(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;
- mHistory.recordWakelockStartEvent(elapsedRealtimeMs, uptimeMs, historyName,
- mappedUid);
- } else if (!mWakeLockImportant && !unimportantForLogging) {
- if (mHistory.maybeUpdateWakelockTag(elapsedRealtimeMs, uptimeMs, historyName,
- mappedUid)) {
- mWakeLockImportant = true;
+ 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);
}
+ mWakeLockImportant = true;
}
mWakeLockNesting++;
}
@@ -4632,13 +5087,15 @@
}
if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
mappedUid, 0)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid);
}
}
if (mWakeLockNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WAKE_LOCK_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
if (mappedUid >= 0) {
@@ -4829,7 +5286,7 @@
mappedUid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
+ addHistoryEventLocked(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
@@ -4882,7 +5339,7 @@
mappedUid, 0)) {
return;
}
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
+ addHistoryEventLocked(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.
@@ -4904,10 +5361,15 @@
@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);
- mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason);
+ mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
+ mHistoryCur.wakeReasonTag.string = reason;
+ mHistoryCur.wakeReasonTag.uid = 0;
mLastWakeupReason = reason;
mLastWakeupUptimeMs = uptimeMs;
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
@GuardedBy("this")
@@ -4918,11 +5380,22 @@
@GuardedBy("this")
public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs,
- int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs,
- int statSoftIrqTimeMs, int statIdleTimeMs) {
- mStepDetailsCalculator.addCpuStats(totalUTimeMs, totalSTimeMs, statUserTimeMs,
- statSystemTimeMs, statIOWaitTimeMs, statIrqTimeMs,
- statSoftIrqTimeMs, statIdleTimeMs);
+ 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;
}
public void noteProcessDiedLocked(int uid, int pid) {
@@ -4952,8 +5425,10 @@
public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mSensorNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_SENSOR_ON_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mSensorNesting++;
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -4970,8 +5445,10 @@
uid = mapUid(uid);
mSensorNesting--;
if (mSensorNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_SENSOR_ON_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
.noteStopSensor(sensor, elapsedRealtimeMs);
@@ -5021,8 +5498,10 @@
}
final int mappedUid = mapUid(uid);
if (mGpsNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_GPS_ON_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mGpsNesting++;
@@ -5047,8 +5526,10 @@
final int mappedUid = mapUid(uid);
mGpsNesting--;
if (mGpsNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_GPS_ON_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs);
mGpsSignalQualityBin = -1;
}
@@ -5081,9 +5562,12 @@
if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) {
mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs);
}
- mHistory.recordGpsSignalQualityEvent(elapsedRealtimeMs, uptimeMs, signalLevel);
+ mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
+ | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGpsSignalQualityBin = signalLevel;
}
+ return;
}
@GuardedBy("this")
@@ -5256,33 +5740,41 @@
}
}
- int startStates = 0;
- int stopStates = 0;
+ boolean updateHistory = false;
if (Display.isDozeState(state) && !Display.isDozeState(oldState)) {
- startStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
+ mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs);
+ updateHistory = true;
} else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) {
- stopStates |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
+ mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG;
mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
+ updateHistory = true;
}
if (Display.isOnState(state)) {
- startStates |= HistoryItem.STATE_SCREEN_ON_FLAG;
+ mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
+ + Integer.toHexString(mHistoryCur.states));
mScreenOnTimer.startRunningLocked(elapsedRealtimeMs);
if (mScreenBrightnessBin >= 0) {
mScreenBrightnessTimer[mScreenBrightnessBin]
.startRunningLocked(elapsedRealtimeMs);
}
+ updateHistory = true;
} else if (Display.isOnState(oldState)) {
- stopStates |= HistoryItem.STATE_SCREEN_ON_FLAG;
+ mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
+ + Integer.toHexString(mHistoryCur.states));
mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (mScreenBrightnessBin >= 0) {
mScreenBrightnessTimer[mScreenBrightnessBin]
.stopRunningLocked(elapsedRealtimeMs);
}
+ updateHistory = true;
}
- if (startStates != 0 || stopStates != 0) {
- mHistory.recordStateChangeEvent(elapsedRealtimeMs, uptimeMs, startStates,
- stopStates);
+ if (updateHistory) {
+ if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: "
+ + Display.stateToString(state));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
// Per screen state Cpu stats needed. Prepare to schedule an external sync.
@@ -5396,7 +5888,13 @@
long uptimeMs) {
if (mScreenBrightnessBin != overallBin) {
if (overallBin >= 0) {
- mHistory.recordScreenBrightnessEvent(elapsedRealtimeMs, uptimeMs, overallBin);
+ 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);
}
if (mScreenState == Display.STATE_ON) {
if (mScreenBrightnessBin >= 0) {
@@ -5423,8 +5921,8 @@
@GuardedBy("this")
public void noteWakeUpLocked(String reason, int reasonUid,
long elapsedRealtimeMs, long uptimeMs) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason,
- reasonUid);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP,
+ reason, reasonUid);
}
@GuardedBy("this")
@@ -5443,7 +5941,7 @@
@GuardedBy("this")
public void noteConnectivityChangedLocked(int type, String extra,
long elapsedRealtimeMs, long uptimeMs) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
extra, type);
mNumConnectivityChange++;
}
@@ -5452,7 +5950,7 @@
private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis,
final long uptimeMillis, int uid) {
uid = mapUid(uid);
- mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
+ addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
uid);
getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked();
}
@@ -5478,8 +5976,7 @@
}
mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
} else {
realElapsedRealtimeMs = timestampNs / (1000*1000);
long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs;
@@ -5491,9 +5988,11 @@
mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs
- realElapsedRealtimeMs);
}
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG);
+ mHistoryCur.states &= ~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.
@@ -5543,14 +6042,17 @@
mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
mPowerSaveModeEnabled = enabled;
if (enabled) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_POWER_SAVE_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
+ + Integer.toHexString(mHistoryCur.states2));
mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs);
} else {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_POWER_SAVE_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
+ + Integer.toHexString(mHistoryCur.states2));
mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs);
}
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED,
enabled
? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON
@@ -5574,7 +6076,7 @@
nowLightIdling = true;
}
if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE,
activeReason, activeUid);
}
if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) {
@@ -5604,7 +6106,11 @@
}
}
if (mDeviceIdleMode != mode) {
- mHistory.recordDeviceIdleEvent(elapsedRealtimeMs, uptimeMs, 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);
long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs;
mLastIdleTimeStartMs = elapsedRealtimeMs;
if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
@@ -5632,7 +6138,7 @@
public void notePackageInstalledLocked(String pkgName, long versionCode,
long elapsedRealtimeMs, long uptimeMs) {
// XXX need to figure out what to do with long version codes.
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED,
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED,
pkgName, (int)versionCode);
PackageChange pc = new PackageChange();
pc.mPackageName = pkgName;
@@ -5644,8 +6150,8 @@
@GuardedBy("this")
public void notePackageUninstalledLocked(String pkgName,
long elapsedRealtimeMs, long uptimeMs) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
- pkgName, 0);
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs,
+ HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0);
PackageChange pc = new PackageChange();
pc.mPackageName = pkgName;
pc.mUpdate = true;
@@ -5674,8 +6180,10 @@
@GuardedBy("this")
public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) {
if (!mPhoneOn) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_PHONE_IN_CALL_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mPhoneOn = true;
mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs);
}
@@ -5684,8 +6192,10 @@
@GuardedBy("this")
public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mPhoneOn) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_PHONE_IN_CALL_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mPhoneOn = false;
mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
@@ -5723,12 +6233,11 @@
if (mUsbDataState != newState) {
mUsbDataState = newState;
if (connected) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_USB_DATA_LINK_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG;
} else {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_USB_DATA_LINK_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG;
}
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
@@ -5749,10 +6258,6 @@
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;
@@ -5781,8 +6286,10 @@
scanning = true;
strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (!mPhoneSignalScanningTimer.isRunningLocked()) {
- addStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG;
+ mHistoryCur.states |= 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);
@@ -5792,7 +6299,9 @@
if (!scanning) {
// If we are no longer scanning, then stop the scanning timer.
if (mPhoneSignalScanningTimer.isRunningLocked()) {
- removeStateFlag = HistoryItem.STATE_PHONE_SCANNING_FLAG;
+ mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
+ + Integer.toHexString(mHistoryCur.states));
newHistory = true;
mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs);
FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state,
@@ -5801,7 +6310,10 @@
}
if (mPhoneServiceState != state) {
- newState = 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));
newHistory = true;
mPhoneServiceState = state;
}
@@ -5815,7 +6327,11 @@
if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
}
- newSignalStrength = strengthBin;
+ 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));
newHistory = true;
FrameworkStatsLog.write(
FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin);
@@ -5826,8 +6342,7 @@
}
if (newHistory) {
- mHistory.recordPhoneStateChangeEvent(elapsedRealtimeMs, uptimeMs,
- addStateFlag, removeStateFlag, newState, newSignalStrength);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
@@ -5951,7 +6466,11 @@
if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
if (mPhoneDataConnectionType != bin) {
- mHistory.recordDataConnectionTypeChangeEvent(elapsedRealtimeMs, uptimeMs, 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);
if (mPhoneDataConnectionType >= 0) {
mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
elapsedRealtimeMs);
@@ -6024,8 +6543,10 @@
@GuardedBy("this")
public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) {
if (!mWifiOn) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_WIFI_ON_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mWifiOn = true;
mWifiOnTimer.startRunningLocked(elapsedRealtimeMs);
scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
@@ -6035,8 +6556,10 @@
@GuardedBy("this")
public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mWifiOn) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_WIFI_ON_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs);
scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
@@ -6047,8 +6570,10 @@
public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mAudioOnNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_AUDIO_ON_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mAudioOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mAudioOnNesting++;
@@ -6063,8 +6588,10 @@
}
uid = mapUid(uid);
if (--mAudioOnNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_AUDIO_ON_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6075,8 +6602,10 @@
public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mVideoOnNesting == 0) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_VIDEO_ON_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mVideoOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mVideoOnNesting++;
@@ -6091,8 +6620,10 @@
}
uid = mapUid(uid);
if (--mVideoOnNesting == 0) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_VIDEO_ON_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6103,8 +6634,10 @@
public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mAudioOnNesting > 0) {
mAudioOnNesting = 0;
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_AUDIO_ON_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6117,8 +6650,10 @@
public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mVideoOnNesting > 0) {
mVideoOnNesting = 0;
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_VIDEO_ON_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6170,8 +6705,10 @@
public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mFlashlightOnNesting++ == 0) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_FLASHLIGHT_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6185,8 +6722,10 @@
}
uid = mapUid(uid);
if (--mFlashlightOnNesting == 0) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_FLASHLIGHT_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6197,8 +6736,10 @@
public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mCameraOnNesting++ == 0) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_CAMERA_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mCameraOnTimer.startRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6212,8 +6753,10 @@
}
uid = mapUid(uid);
if (--mCameraOnNesting == 0) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_CAMERA_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6224,8 +6767,10 @@
public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mCameraOnNesting > 0) {
mCameraOnNesting = 0;
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_CAMERA_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6238,8 +6783,10 @@
public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mFlashlightOnNesting > 0) {
mFlashlightOnNesting = 0;
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_FLASHLIGHT_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6256,8 +6803,10 @@
}
uid = mapUid(uid);
if (mBluetoothScanNesting == 0) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs);
}
mBluetoothScanNesting++;
@@ -6298,8 +6847,10 @@
uid = mapUid(uid);
mBluetoothScanNesting--;
if (mBluetoothScanNesting == 0) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6334,8 +6885,10 @@
public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) {
if (mBluetoothScanNesting > 0) {
mBluetoothScanNesting = 0;
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
@@ -6375,7 +6928,7 @@
private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
final long uptimeMillis, int uid) {
uid = mapUid(uid);
- mHistory.recordEvent(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
+ addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
uid);
getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked();
}
@@ -6391,14 +6944,15 @@
if (uid > 0) {
noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid);
}
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs);
} else {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG);
+ mHistoryCur.states &= ~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;
}
}
@@ -6406,8 +6960,10 @@
@GuardedBy("this")
public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
if (!mGlobalWifiRunning) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_WIFI_RUNNING_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGlobalWifiRunning = true;
mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
int N = ws.size();
@@ -6475,8 +7031,10 @@
@GuardedBy("this")
public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) {
if (mGlobalWifiRunning) {
- mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_WIFI_RUNNING_FLAG);
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mGlobalWifiRunning = false;
mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
int N = ws.size();
@@ -6524,7 +7082,12 @@
}
mWifiSupplState = supplState;
mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs);
- mHistory.recordWifiSupplicantStateChangeEvent(elapsedRealtimeMs, uptimeMs, supplState);
+ 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);
}
}
@@ -6553,8 +7116,12 @@
if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs);
}
- mHistory.recordWifiSignalStrengthChangeEvent(elapsedRealtimeMs, uptimeMs,
- strengthBin);
+ 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);
} else {
stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs);
}
@@ -6567,8 +7134,10 @@
@GuardedBy("this")
public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mWifiFullLockNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_FULL_LOCK_FLAG);
+ 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);
}
mWifiFullLockNesting++;
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6579,8 +7148,10 @@
public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
mWifiFullLockNesting--;
if (mWifiFullLockNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_FULL_LOCK_FLAG);
+ 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);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
.noteFullWifiLockReleasedLocked(elapsedRealtimeMs);
@@ -6596,8 +7167,10 @@
@GuardedBy("this")
public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
if (mWifiScanNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_SCAN_FLAG);
+ mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
mWifiScanNesting++;
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
@@ -6613,8 +7186,10 @@
public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
mWifiScanNesting--;
if (mWifiScanNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_SCAN_FLAG);
+ mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
+ + Integer.toHexString(mHistoryCur.states));
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
.noteWifiScanStoppedLocked(elapsedRealtimeMs);
@@ -6639,10 +7214,14 @@
public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
uid = mapUid(uid);
if (mWifiMulticastNesting == 0) {
- mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG);
+ 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);
+
// Start Wifi Multicast overall timer
if (!mWifiMulticastWakelockTimer.isRunningLocked()) {
+ if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started");
mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs);
}
}
@@ -6656,12 +7235,14 @@
uid = mapUid(uid);
mWifiMulticastNesting--;
if (mWifiMulticastNesting == 0) {
- mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG);
+ 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);
// Stop Wifi Multicast overall timer
if (mWifiMulticastWakelockTimer.isRunningLocked()) {
- if (DEBUG) Slog.v(TAG, "Multicast Overall Timer Stopped");
+ if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped");
mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
}
}
@@ -7413,9 +7994,8 @@
// 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.
- mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(),
- currentTimeMs
- );
+ recordCurrentTimeChangeLocked(currentTimeMs, mClock.elapsedRealtime(),
+ mClock.uptimeMillis());
return currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000));
}
return mStartClockTimeMs;
@@ -10647,19 +11227,18 @@
UserInfoProvider userInfoProvider) {
init(clock);
- mHandler = new MyHandler(handler.getLooper());
- mConstants = new Constants(mHandler);
-
if (systemDir == null) {
mStatsFile = null;
- mHistory = new BatteryStatsHistory(mStepDetailsCalculator, mClock);
+ mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
} else {
mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin"));
- mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES,
- mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock);
+ mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer, systemDir,
+ this::getMaxHistoryFiles);
}
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;
@@ -10668,6 +11247,7 @@
initTimes(uptimeUs, realtimeUs);
mStartPlatformVersion = mEndPlatformVersion = Build.ID;
initDischarge(realtimeUs);
+ clearHistoryLocked();
updateDailyDeadlineLocked();
mPlatformIdleStateCallback = cb;
mMeasuredEnergyRetriever = energyStatsCb;
@@ -10678,6 +11258,12 @@
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);
@@ -10759,7 +11345,7 @@
mDischargeUnplugLevel = 0;
mDischargePlugLevel = -1;
mDischargeCurrentLevel = 0;
- mBatteryLevel = 0;
+ mCurrentBatteryLevel = 0;
}
public void setPowerProfileLocked(PowerProfile profile) {
@@ -11146,7 +11732,7 @@
}
public int getHistoryUsedSize() {
- return mHistory.getHistoryUsedSize();
+ return mBatteryStatsHistory.getHistoryUsedSize();
}
@Override
@@ -11160,27 +11746,43 @@
*/
@VisibleForTesting
public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() {
- return mHistory.iterate();
+ return new BatteryStatsHistoryIterator(mBatteryStatsHistory);
}
@Override
public int getHistoryStringPoolSize() {
- return mHistory.getHistoryStringPoolSize();
+ return mHistoryTagPool.size();
}
@Override
public int getHistoryStringPoolBytes() {
- return mHistory.getHistoryStringPoolBytes();
+ return mNumHistoryTagChars;
}
@Override
public String getHistoryTagPoolString(int index) {
- return mHistory.getHistoryTagPoolString(index);
+ ensureHistoryTagArray();
+ HistoryTag historyTag = mHistoryTags.get(index);
+ return historyTag != null ? historyTag.string : null;
}
@Override
public int getHistoryTagPoolUid(int index) {
- return mHistory.getHistoryTagPoolUid(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());
+ }
}
@Override
@@ -11190,11 +11792,15 @@
@Override
public void finishIteratingHistoryLocked() {
- mBatteryStatsHistoryIterator.close();
mBatteryStatsHistoryIterator = null;
}
@Override
+ public long getHistoryBaseTime() {
+ return mHistoryBaseTimeMs;
+ }
+
+ @Override
public int getStartCount() {
return mStartCount;
}
@@ -11247,23 +11853,24 @@
long realtimeUs = mSecRealtime * 1000;
resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
pullPendingStateUpdatesLocked();
- mHistory.writeHistoryItem(mSecRealtime, mSecUptime);
- mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mBatteryLevel;
+ addHistoryRecordLocked(mSecRealtime, mSecUptime);
+ mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
+ = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
mOnBatteryTimeBase.reset(uptimeUs, realtimeUs);
mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs);
- if (!mBatteryPluggedIn) {
+ if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
if (Display.isOnState(mScreenState)) {
- mDischargeScreenOnUnplugLevel = mBatteryLevel;
+ mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
mDischargeScreenDozeUnplugLevel = 0;
mDischargeScreenOffUnplugLevel = 0;
} else if (Display.isDozeState(mScreenState)) {
mDischargeScreenOnUnplugLevel = 0;
- mDischargeScreenDozeUnplugLevel = mBatteryLevel;
+ mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel;
mDischargeScreenOffUnplugLevel = 0;
} else {
mDischargeScreenOnUnplugLevel = 0;
mDischargeScreenDozeUnplugLevel = 0;
- mDischargeScreenOffUnplugLevel = mBatteryLevel;
+ mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
}
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenOff = 0;
@@ -11407,12 +12014,27 @@
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);
- mHistory.reset();
+ clearHistoryLocked();
+ if (mBatteryStatsHistory != null) {
+ mBatteryStatsHistory.resetAllFiles();
+ }
// Flush external data, gathering snapshots, but don't process it since it is pre-reset data
mIgnoreNextExternalStats = true;
@@ -11435,7 +12057,7 @@
for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
SparseIntArray uids = ent.getValue();
for (int j=0; j<uids.size(); j++) {
- mHistory.recordEvent(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
+ addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
uids.keyAt(j));
}
}
@@ -11860,8 +12482,9 @@
(long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt);
mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
monitoredRailChargeConsumedMaMs);
- mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs,
- (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
+ mHistoryCur.wifiRailChargeMah +=
+ (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mTmpRailStats.resetWifiTotalEnergyUsed();
if (uidEstimatedConsumptionMah != null) {
@@ -11974,8 +12597,9 @@
(long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt);
mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
monitoredRailChargeConsumedMaMs);
- mHistory.recordWifiConsumedCharge(elapsedRealtimeMs, uptimeMs,
- (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
+ mHistoryCur.modemRailChargeMah +=
+ (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mTmpRailStats.resetCellularTotalEnergyUsed();
}
@@ -12243,8 +12867,8 @@
}
}
if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) {
- mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG);
+ mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
@@ -13677,7 +14301,11 @@
mHandler.removeCallbacks(mDeferSetCharging);
if (mCharging != charging) {
mCharging = charging;
- mHistory.setChargingState(charging);
+ if (charging) {
+ mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
+ } else {
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
+ }
mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
return true;
}
@@ -13691,15 +14319,6 @@
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) {
@@ -13783,12 +14402,15 @@
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) {
- mHistory.startRecordingHistory(mSecRealtime, mSecUptime, reset);
- initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
+ mRecordingHistory = true;
+ startRecordingHistory(mSecRealtime, mSecUptime, reset);
}
- mBatteryPluggedIn = false;
- mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn);
+ addHistoryRecordLocked(mSecRealtime, mSecUptime);
mDischargeCurrentLevel = mDischargeUnplugLevel = level;
if (Display.isOnState(screenState)) {
mDischargeScreenOnUnplugLevel = level;
@@ -13810,8 +14432,11 @@
} else {
mOnBattery = mOnBatteryInternal = false;
pullPendingStateUpdatesLocked();
- mBatteryPluggedIn = true;
- mHistory.recordBatteryState(mSecRealtime, mSecUptime, level, mBatteryPluggedIn);
+ 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);
mDischargeCurrentLevel = mDischargePlugLevel = level;
if (level < mDischargeUnplugLevel) {
mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
@@ -13826,12 +14451,45 @@
mModStepMode = 0;
}
if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) {
- if (mStatsFile != null && !mHistory.isReadOnly()) {
+ if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) {
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);
@@ -13849,7 +14507,8 @@
// Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
temp = Math.max(0, temp);
- reportChangesToStatsLog(status, plugType, level);
+ reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
+ status, plugType, level);
final boolean onBattery = isOnBattery(plugType, status);
if (!mHaveBatteryLevel) {
@@ -13859,47 +14518,52 @@
// plugged in, then twiddle our state to correctly reflect that
// since we won't be going through the full setOnBattery().
if (onBattery == mOnBattery) {
- mHistory.setPluggedInState(!onBattery);
+ if (onBattery) {
+ mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ } else {
+ mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
+ }
}
- mBatteryStatus = status;
- mBatteryLevel = level;
- mBatteryChargeUah = chargeUah;
-
// Always start out assuming charging, that will be updated later.
- mHistory.setBatteryState(true /* charging */, status, level, chargeUah);
-
+ mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
+ mHistoryCur.batteryStatus = (byte)status;
+ mHistoryCur.batteryLevel = (byte)level;
+ mHistoryCur.batteryChargeUah = chargeUah;
mMaxChargeStepLevel = mMinDischargeStepLevel =
mLastChargeStepLevel = mLastDischargeStepLevel = level;
- } else if (mBatteryLevel != level || mOnBattery != onBattery) {
+ } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs);
}
- int oldStatus = mBatteryStatus;
+ int oldStatus = mHistoryCur.batteryStatus;
if (onBattery) {
mDischargeCurrentLevel = level;
- if (!mHistory.isRecordingHistory()) {
- mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
}
} else if (level < 96 &&
status != BatteryManager.BATTERY_STATUS_UNKNOWN) {
- if (!mHistory.isRecordingHistory()) {
- mHistory.startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtimeMs, uptimeMs, true);
}
}
+ mBatteryVoltageMv = voltageMv;
+ mCurrentBatteryLevel = level;
if (mDischargePlugLevel < 0) {
mDischargePlugLevel = level;
}
if (onBattery != mOnBattery) {
- mBatteryLevel = level;
- mBatteryStatus = status;
- mBatteryHealth = health;
- mBatteryPlugType = plugType;
- mBatteryTemperature = temp;
- mBatteryVoltageMv = voltageMv;
- mHistory.setBatteryState(status, level, health, plugType, temp, voltageMv, chargeUah);
- if (chargeUah < mBatteryChargeUah) {
+ 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) {
// Only record discharges
- final long chargeDiff = (long) mBatteryChargeUah - chargeUah;
+ final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah;
mDischargeCounter.addCountLocked(chargeDiff);
mDischargeScreenOffCounter.addCountLocked(chargeDiff);
if (Display.isDozeState(mScreenState)) {
@@ -13911,12 +14575,12 @@
mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
}
}
- mBatteryChargeUah = chargeUah;
+ mHistoryCur.batteryChargeUah = chargeUah;
setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah);
} else {
boolean changed = false;
- if (mBatteryLevel != level) {
- mBatteryLevel = level;
+ if (mHistoryCur.batteryLevel != level) {
+ mHistoryCur.batteryLevel = (byte)level;
changed = true;
// TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
@@ -13924,33 +14588,33 @@
mExternalSync.scheduleSyncDueToBatteryLevelChange(
mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS);
}
- if (mBatteryStatus != status) {
- mBatteryStatus = status;
+ if (mHistoryCur.batteryStatus != status) {
+ mHistoryCur.batteryStatus = (byte)status;
changed = true;
}
- if (mBatteryHealth != health) {
- mBatteryHealth = health;
+ if (mHistoryCur.batteryHealth != health) {
+ mHistoryCur.batteryHealth = (byte)health;
changed = true;
}
- if (mBatteryPlugType != plugType) {
- mBatteryPlugType = plugType;
+ if (mHistoryCur.batteryPlugType != plugType) {
+ mHistoryCur.batteryPlugType = (byte)plugType;
changed = true;
}
- if (temp >= (mBatteryTemperature + 10)
- || temp <= (mBatteryTemperature - 10)) {
- mBatteryTemperature = temp;
+ if (temp >= (mHistoryCur.batteryTemperature+10)
+ || temp <= (mHistoryCur.batteryTemperature-10)) {
+ mHistoryCur.batteryTemperature = (short)temp;
changed = true;
}
- if (voltageMv > (mBatteryVoltageMv + 20)
- || voltageMv < (mBatteryVoltageMv - 20)) {
- mBatteryVoltageMv = voltageMv;
+ if (voltageMv > (mHistoryCur.batteryVoltage + 20)
+ || voltageMv < (mHistoryCur.batteryVoltage - 20)) {
+ mHistoryCur.batteryVoltage = (char) voltageMv;
changed = true;
}
- if (chargeUah >= (mBatteryChargeUah + 10)
- || chargeUah <= (mBatteryChargeUah - 10)) {
- if (chargeUah < mBatteryChargeUah) {
+ if (chargeUah >= (mHistoryCur.batteryChargeUah + 10)
+ || chargeUah <= (mHistoryCur.batteryChargeUah - 10)) {
+ if (chargeUah < mHistoryCur.batteryChargeUah) {
// Only record discharges
- final long chargeDiff = (long) mBatteryChargeUah - chargeUah;
+ final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah;
mDischargeCounter.addCountLocked(chargeDiff);
mDischargeScreenOffCounter.addCountLocked(chargeDiff);
if (Display.isDozeState(mScreenState)) {
@@ -13962,10 +14626,9 @@
mDischargeDeepDozeCounter.addCountLocked(chargeDiff);
}
}
- mBatteryChargeUah = chargeUah;
+ mHistoryCur.batteryChargeUah = 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);
@@ -14023,10 +14686,7 @@
mLastChargeStepLevel = level;
}
if (changed) {
- mHistory.setBatteryState(mBatteryStatus, mBatteryLevel, mBatteryHealth,
- mBatteryPlugType, mBatteryTemperature, mBatteryVoltageMv,
- mBatteryChargeUah);
- mHistory.writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
}
}
if (!onBattery &&
@@ -14035,7 +14695,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.
- mHistory.setHistoryRecordingEnabled(DEBUG);
+ mRecordingHistory = DEBUG;
}
mLastLearnedBatteryCapacityUah = chargeFullUah;
@@ -14054,18 +14714,17 @@
}
// Inform StatsLog of setBatteryState changes.
- private void reportChangesToStatsLog(final int status, final int plugType, final int level) {
- if (!mHaveBatteryLevel) {
- return;
- }
+ // If this is the first reporting, pass in recentPast == null.
+ private void reportChangesToStatsLog(HistoryItem recentPast,
+ final int status, final int plugType, final int level) {
- if (mBatteryStatus != status) {
+ if (recentPast == null || recentPast.batteryStatus != status) {
FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status);
}
- if (mBatteryPlugType != plugType) {
+ if (recentPast == null || recentPast.batteryPlugType != plugType) {
FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType);
}
- if (mBatteryLevel != level) {
+ if (recentPast == null || recentPast.batteryLevel != level) {
FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level);
}
}
@@ -14135,7 +14794,7 @@
if (msPerLevel <= 0) {
return -1;
}
- return (msPerLevel * mBatteryLevel) * 1000;
+ return (msPerLevel * mCurrentBatteryLevel) * 1000;
}
@Override
@@ -14165,7 +14824,7 @@
if (msPerLevel <= 0) {
return -1;
}
- return (msPerLevel * (100 - mBatteryLevel)) * 1000;
+ return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000;
}
/*@hide */
@@ -14596,8 +15255,7 @@
@GuardedBy("this")
public void shutdownLocked() {
- mHistory.recordShutdownEvent(mClock.elapsedRealtime(), mClock.uptimeMillis(),
- mClock.currentTimeMillis());
+ recordShutdownLocked(mClock.currentTimeMillis(), mClock.elapsedRealtime());
writeSyncLocked();
mShuttingDown = true;
}
@@ -14805,6 +15463,7 @@
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
@@ -14815,20 +15474,9 @@
: 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,
@@ -15049,11 +15697,27 @@
}
private void writeHistoryLocked() {
+ if (mBatteryStatsHistory.getActiveFile() == null) {
+ Slog.w(TAG, "writeHistoryLocked: no history file associated with this instance");
+ return;
+ }
+
if (mShuttingDown) {
return;
}
- mHistory.writeHistory();
+ 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();
+ }
}
private final ReentrantLock mWriteLock = new ReentrantLock();
@@ -15092,6 +15756,13 @@
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();
@@ -15104,7 +15775,7 @@
readSummaryFromParcel(stats);
if (DEBUG) {
Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath()
- + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis()
+ + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis()
- start));
}
}
@@ -15116,19 +15787,126 @@
stats.recycle();
}
- if (!mHistory.readSummary()) {
- resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(),
- RESET_REASON_CORRUPT_FILE);
+ 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();
}
mEndPlatformVersion = Build.ID;
- mHistory.continueRecordingHistory();
+ 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);
+ }
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();
@@ -15138,7 +15916,31 @@
return;
}
- mHistory.readSummaryFromParcel(in);
+ 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;
+ }
mStartCount = in.readInt();
mUptimeUs = in.readLong();
@@ -15151,7 +15953,7 @@
mDischargeUnplugLevel = in.readInt();
mDischargePlugLevel = in.readInt();
mDischargeCurrentLevel = in.readInt();
- mBatteryLevel = in.readInt();
+ mCurrentBatteryLevel = in.readInt();
mEstimatedBatteryCapacityMah = in.readInt();
mLastLearnedBatteryCapacityUah = in.readInt();
mMinLearnedBatteryCapacityUah = in.readInt();
@@ -15654,7 +16456,19 @@
out.writeInt(VERSION);
- mHistory.writeSummaryToParcel(out, inclHistory);
+ 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);
+ }
out.writeInt(mStartCount);
out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED));
@@ -15667,7 +16481,7 @@
out.writeInt(mDischargeUnplugLevel);
out.writeInt(mDischargePlugLevel);
out.writeInt(mDischargeCurrentLevel);
- out.writeInt(mBatteryLevel);
+ out.writeInt(mCurrentBatteryLevel);
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 c36d950..0cdd4d1 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -22,6 +22,7 @@
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;
@@ -31,8 +32,10 @@
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;
@@ -217,7 +220,18 @@
}
BatteryStatsImpl batteryStatsImpl = (BatteryStatsImpl) mStats;
- batteryUsageStatsBuilder.setBatteryHistory(batteryStatsImpl.copyHistory());
+
+ // 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);
}
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 5c934852..61a7f38 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,7 +28,6 @@
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;
@@ -50,14 +49,13 @@
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, "battery-history");
+ mHistoryDir = new File(mSystemDir, BatteryStatsHistory.HISTORY_DIR);
String[] files = mHistoryDir.list();
if (files != null) {
for (int i = 0; i < files.length; i++) {
@@ -69,8 +67,8 @@
@Test
public void testConstruct() {
- BatteryStatsHistory history = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
- null, mClock);
+ BatteryStatsHistory history =
+ new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
createActiveFile(history);
verifyFileNumbers(history, Arrays.asList(0));
verifyActiveFile(history, "0.bin");
@@ -78,8 +76,8 @@
@Test
public void testStartNextFile() {
- BatteryStatsHistory history = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
- null, mClock);
+ BatteryStatsHistory history =
+ new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
List<Integer> fileList = new ArrayList<>();
fileList.add(0);
createActiveFile(history);
@@ -116,13 +114,13 @@
assertEquals(0, history.getHistoryUsedSize());
// create a new BatteryStatsHistory object, it will pick up existing history files.
- BatteryStatsHistory history2 = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
- null, mClock);
- // verify constructor can pick up all files from file system.
+ BatteryStatsHistory history2 =
+ new BatteryStatsHistory(mHistoryBuffer, mSystemDir, () -> 32);
+ // verify construct can pick up all files from file system.
verifyFileNumbers(history2, fileList);
verifyActiveFile(history2, "33.bin");
- history2.reset();
+ history2.resetAllFiles();
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 570b2ee..713e786 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,7 +63,6 @@
MockBatteryStatsImpl(Clock clock, File historyDirectory) {
super(clock, historyDirectory);
initTimersAndCounters();
- setMaxHistoryBuffer(128 * 1024);
setExternalStatsSyncLocked(mExternalStatsSync);
informThatAllExternalStatsAreFlushed();
@@ -105,6 +104,12 @@
return mForceOnBattery ? true : super.isOnBattery();
}
+ public void forceRecordAllHistory() {
+ mHaveBatteryLevel = true;
+ mRecordingHistory = true;
+ mRecordAllHistory = true;
+ }
+
public TimeBase getOnBatteryBackgroundTimeBase(int uid) {
return getUidStatsLocked(uid).mOnBatteryBackgroundTimeBase;
}
@@ -196,14 +201,12 @@
@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;
}