Export BatteryStats info to Atrace.
This is a tm-qpr re-write of http://ag/19779936 and http://ag/19806033. There was large refactor of BatteryStatsHistory that prevent the changes from being cherry-picked directly. Instead, this change copies the relevant sections and stitches together the rest. Things that are identical * The whole TraceDelegate * recordTraceCounters * recordTraceEvents Things that are different * Record calls are moved to BatteryStatsImpl * Class setup (mTracer isn't changeable) * No tests (can be added, but hard prior to the refactor) Bug: 245749764 Test: presubmit and local perfetto tracing Merged-In: Iaae4e9796a44be3ffdaee31b956bbb3e87735ead Change-Id: I62fc2e93b662b89176cc26bdff8b3e88d216028a
This commit is contained in:
@@ -16,12 +16,20 @@
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStats.BitDescription;
|
||||
import android.os.BatteryStats.HistoryItem;
|
||||
import android.os.BatteryStats.HistoryTag;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Process;
|
||||
import android.os.StatFs;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Slog;
|
||||
@@ -104,6 +112,49 @@ public class BatteryStatsHistory {
|
||||
*/
|
||||
private int mParcelIndex = 0;
|
||||
|
||||
/**
|
||||
* A delegate for android.os.Trace to allow testing static calls. Due to
|
||||
* limitations in Android Tracing (b/153319140), the delegate also records
|
||||
* counter values in system properties which allows reading the value at the
|
||||
* start of a tracing session. This overhead is limited to userdebug builds.
|
||||
* On user builds, tracing still occurs but the counter value will be missing
|
||||
* until the first change occurs.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static class TraceDelegate {
|
||||
// Note: certain tests currently run as platform_app which is not allowed
|
||||
// to set debug system properties. To ensure that system properties are set
|
||||
// only when allowed, we check the current UID.
|
||||
private final boolean mShouldSetProperty =
|
||||
Build.IS_USERDEBUG && (Process.myUid() == Process.SYSTEM_UID);
|
||||
|
||||
/**
|
||||
* Returns true if trace counters should be recorded.
|
||||
*/
|
||||
public boolean tracingEnabled() {
|
||||
return Trace.isTagEnabled(Trace.TRACE_TAG_POWER) || mShouldSetProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the counter value with the given name.
|
||||
*/
|
||||
public void traceCounter(@NonNull String name, int value) {
|
||||
Trace.traceCounter(Trace.TRACE_TAG_POWER, name, value);
|
||||
if (mShouldSetProperty) {
|
||||
SystemProperties.set("debug.tracing." + name, Integer.toString(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an instant event (one with no duration).
|
||||
*/
|
||||
public void traceInstantEvent(@NonNull String track, @NonNull String name) {
|
||||
Trace.instantForTrack(Trace.TRACE_TAG_POWER, track, name);
|
||||
}
|
||||
}
|
||||
|
||||
private TraceDelegate mTracer = new TraceDelegate();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param stats BatteryStatsImpl object.
|
||||
@@ -497,4 +548,47 @@ public class BatteryStatsHistory {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes event details into Atrace.
|
||||
*/
|
||||
public void recordTraceEvents(int code, HistoryTag tag) {
|
||||
if (code == HistoryItem.EVENT_NONE) return;
|
||||
if (!mTracer.tracingEnabled()) return;
|
||||
|
||||
final int idx = code & HistoryItem.EVENT_TYPE_MASK;
|
||||
final String prefix = (code & HistoryItem.EVENT_FLAG_START) != 0 ? "+" :
|
||||
(code & HistoryItem.EVENT_FLAG_FINISH) != 0 ? "-" : "";
|
||||
|
||||
final String[] names = BatteryStats.HISTORY_EVENT_NAMES;
|
||||
if (idx < 0 || idx >= BatteryStats.HISTORY_EVENT_NAMES.length) return;
|
||||
|
||||
final String track = "battery_stats." + names[idx];
|
||||
final String name = prefix + names[idx] + "=" + tag.uid + ":\"" + tag.string + "\"";
|
||||
mTracer.traceInstantEvent(track, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes changes to a HistoryItem state bitmap to Atrace.
|
||||
*/
|
||||
public void recordTraceCounters(int oldval, int newval, BitDescription[] descriptions) {
|
||||
if (!mTracer.tracingEnabled()) return;
|
||||
|
||||
int diff = oldval ^ newval;
|
||||
if (diff == 0) return;
|
||||
|
||||
for (int i = 0; i < descriptions.length; i++) {
|
||||
BitDescription bd = descriptions[i];
|
||||
if ((diff & bd.mask) == 0) continue;
|
||||
|
||||
int value;
|
||||
if (bd.shift < 0) {
|
||||
value = (newval & bd.mask) != 0 ? 1 : 0;
|
||||
} else {
|
||||
value = (newval & bd.mask) >> bd.shift;
|
||||
}
|
||||
|
||||
mTracer.traceCounter("battery_stats." + bd.name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4432,6 +4432,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
+ Integer.toHexString(diffStates2) + " lastDiff2="
|
||||
+ Integer.toHexString(lastDiffStates2));
|
||||
}
|
||||
|
||||
mBatteryStatsHistory.recordTraceEvents(cur.eventCode, cur.eventTag);
|
||||
mBatteryStatsHistory.recordTraceCounters(mHistoryLastWritten.states,
|
||||
cur.states & mActiveHistoryStates, BatteryStats.HISTORY_STATE_DESCRIPTIONS);
|
||||
mBatteryStatsHistory.recordTraceCounters(mHistoryLastWritten.states2,
|
||||
cur.states2 & mActiveHistoryStates2, BatteryStats.HISTORY_STATE2_DESCRIPTIONS);
|
||||
if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
|
||||
&& timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0
|
||||
&& (diffStates2&lastDiffStates2) == 0
|
||||
|
||||
Reference in New Issue
Block a user