summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ryan Zuklie <rzuklie@google.com> 2022-09-16 23:09:20 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-09-16 23:09:20 +0000
commit745d055d20803becba24298d8fadcfcbd92f07fb (patch)
tree812065a36442fa77597b509df955e77951a33842
parent488a69bfc46df63c392a30dfefd112e4cb69a1ce (diff)
parentb48df1b4d1d6d711efaed42f018f36f2b256af0f (diff)
Merge "Export BatteryStats info to Atrace." into tm-qpr-dev
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHistory.java94
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java6
2 files changed, 100 insertions, 0 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index b0fce8f18742..d9df144fe54d 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -17,11 +17,19 @@
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;
@@ -105,6 +113,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.
* @param systemDir typically /data/system
@@ -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);
+ }
+ }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 98d4c5976adc..ec2bc7cde1a0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -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