diff options
| author | 2023-08-15 23:17:50 +0000 | |
|---|---|---|
| committer | 2023-08-15 23:17:50 +0000 | |
| commit | 2a70a73d5a6f7b3afcf875268f20d33767f19de2 (patch) | |
| tree | 999211e23c1e7f7397764e80135bba0c6c506e12 | |
| parent | 7e9ded600a428d632f7c27894eed832611952d28 (diff) | |
| parent | 49fa85a1c0947aa87f0863809387b8ac91c84890 (diff) | |
Merge "Include the history tag string in checkin file verbatim" into main
4 files changed, 116 insertions, 10 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 43219bc38e2d..42c56265bb4a 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1656,6 +1656,8 @@ public abstract class BatteryStats { public abstract CpuScalingPolicies getCpuScalingPolicies(); public final static class HistoryTag { + public static final int HISTORY_TAG_POOL_OVERFLOW = -1; + public String string; public int uid; @@ -6826,10 +6828,11 @@ public abstract class BatteryStats { if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) { didWake = true; sb.append("="); - if (longNames) { + if (longNames + || wakelockTag.poolIdx == HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { UserHandle.formatUid(sb, wakelockTag.uid); sb.append(":\""); - sb.append(wakelockTag.string); + sb.append(wakelockTag.string.replace("\"", "\"\"")); sb.append("\""); } else { sb.append(wakelockTag.poolIdx); @@ -6849,7 +6852,7 @@ public abstract class BatteryStats { } if (!didWake && wakelockTag != null) { sb.append(longNames ? " wake_lock=" : ",w="); - if (longNames) { + if (longNames || wakelockTag.poolIdx == HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { UserHandle.formatUid(sb, wakelockTag.uid); sb.append(":\""); sb.append(wakelockTag.string); @@ -7110,7 +7113,14 @@ public abstract class BatteryStats { if (rec.wakeReasonTag != null) { if (checkin) { item.append(",wr="); - item.append(rec.wakeReasonTag.poolIdx); + if (rec.wakeReasonTag.poolIdx == HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { + item.append(sUidToString.applyAsString(rec.wakeReasonTag.uid)); + item.append(":\""); + item.append(rec.wakeReasonTag.string.replace("\"", "\"\"")); + item.append("\""); + } else { + item.append(rec.wakeReasonTag.poolIdx); + } } else { item.append(" wake_reason="); item.append(rec.wakeReasonTag.uid); @@ -7138,7 +7148,15 @@ public abstract class BatteryStats { } item.append("="); if (checkin) { - item.append(rec.eventTag.poolIdx); + if (rec.eventTag.poolIdx == HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { + item.append(HISTORY_EVENT_INT_FORMATTERS[idx] + .applyAsString(rec.eventTag.uid)); + item.append(":\""); + item.append(rec.eventTag.string.replace("\"", "\"\"")); + item.append("\""); + } else { + item.append(rec.eventTag.poolIdx); + } } else { item.append(HISTORY_EVENT_INT_FORMATTERS[idx] .applyAsString(rec.eventTag.uid)); diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index 0a938ef4d81c..79152b4b618f 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -185,7 +185,7 @@ public class BatteryStatsHistory { private boolean mHaveBatteryLevel; private boolean mRecordingHistory; - private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe; + 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<>(); @@ -1872,6 +1872,7 @@ public class BatteryStatsHistory { } return idx | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG; } else { + tag.poolIdx = HistoryTag.HISTORY_TAG_POOL_OVERFLOW; // Tag pool overflow: include the tag itself in the parcel return HISTORY_TAG_INDEX_LIMIT | BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG; } diff --git a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java index ccc3454624f8..4c2b2854df88 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java +++ b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java @@ -309,7 +309,11 @@ public class BatteryStatsHistoryIterator implements Iterator<BatteryStats.Histor BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag(); tag.readFromParcel(src); tag.poolIdx = index & ~BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG; - mHistoryTags.put(tag.poolIdx, tag); + if (tag.poolIdx < BatteryStatsHistory.HISTORY_TAG_INDEX_LIMIT) { + mHistoryTags.put(tag.poolIdx, tag); + } else { + tag.poolIdx = BatteryStats.HistoryTag.HISTORY_TAG_POOL_OVERFLOW; + } outTag.setTo(tag); } else { diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java index 48ba765c3968..f2cbef69c8e5 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java @@ -38,7 +38,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; -import com.android.internal.os.Clock; import org.junit.Before; import org.junit.Test; @@ -65,7 +64,7 @@ public class BatteryStatsHistoryTest { private final Parcel mHistoryBuffer = Parcel.obtain(); private File mSystemDir; private File mHistoryDir; - private final Clock mClock = new MockClock(); + private final MockClock mClock = new MockClock(); private BatteryStatsHistory mHistory; private BatteryStats.HistoryPrinter mHistoryPrinter; @Mock @@ -486,10 +485,94 @@ public class BatteryStatsHistoryTest { NetworkRegistrationInfo.NR_STATE_NONE); } + @Test + public void largeTagPool() { + // Keep the preserved part of history short - we only need to capture the very tail of + // history. + mHistory = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 1, 6000, + mStepDetailsCalculator, mClock, mTracer); + + mHistory.forceRecordAllHistory(); + + mClock.realtime = 2_000_000; + mClock.uptime = 1_000_000; + // More than 32k strings + final int tagCount = 0x7FFF + 20; + for (int tag = 0; tag < tagCount;) { + mClock.realtime += 10; + mClock.uptime += 10; + mHistory.recordEvent(mClock.realtime, mClock.uptime, HistoryItem.EVENT_ALARM_START, + "a" + (tag++), 42); + + mHistory.setBatteryState(true, BatteryManager.BATTERY_STATUS_CHARGING, tag % 50, 0); + mClock.realtime += 10; + mClock.uptime += 10; + mHistory.recordWakelockStartEvent(mClock.realtime, mClock.uptime, "w" + tag, 42); + mClock.realtime += 10; + mClock.uptime += 10; + mHistory.recordWakelockStopEvent(mClock.realtime, mClock.uptime, "w" + tag, 42); + tag++; + + mHistory.recordWakeupEvent(mClock.realtime, mClock.uptime, "wr" + (tag++)); + } + + int eventTagsPooled = 0; + int eventTagsUnpooled = 0; + int wakelockTagsPooled = 0; + int wakelockTagsUnpooled = 0; + int wakeReasonTagsPooled = 0; + int wakeReasonTagsUnpooled = 0; + for (BatteryStatsHistoryIterator iterator = mHistory.iterate(); iterator.hasNext(); ) { + HistoryItem item = iterator.next(); + if (item.cmd != HistoryItem.CMD_UPDATE) { + continue; + } + String checkinDump = toString(item, true); + if (item.eventCode == HistoryItem.EVENT_ALARM_START) { + if (item.eventTag.poolIdx != BatteryStats.HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { + eventTagsPooled++; + assertThat(checkinDump).contains("+Eal=" + item.eventTag.poolIdx); + } else { + eventTagsUnpooled++; + assertThat(checkinDump).contains("+Eal=42:\"" + item.eventTag.string + "\""); + } + } + + if (item.wakelockTag != null) { + if (item.wakelockTag.poolIdx != BatteryStats.HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { + wakelockTagsPooled++; + assertThat(checkinDump).contains("w=" + item.wakelockTag.poolIdx); + } else { + wakelockTagsUnpooled++; + assertThat(checkinDump).contains("w=42:\"" + item.wakelockTag.string + "\""); + } + } + + if (item.wakeReasonTag != null) { + if (item.wakeReasonTag.poolIdx + != BatteryStats.HistoryTag.HISTORY_TAG_POOL_OVERFLOW) { + wakeReasonTagsPooled++; + assertThat(checkinDump).contains("wr=" + item.wakeReasonTag.poolIdx); + } else { + wakeReasonTagsUnpooled++; + assertThat(checkinDump).contains("wr=0:\"" + item.wakeReasonTag.string + "\""); + } + } + } + + // Self-check - ensure that we have all cases represented in the test + assertThat(eventTagsPooled).isGreaterThan(0); + assertThat(eventTagsUnpooled).isGreaterThan(0); + assertThat(wakelockTagsPooled).isGreaterThan(0); + assertThat(wakelockTagsUnpooled).isGreaterThan(0); + assertThat(wakeReasonTagsPooled).isGreaterThan(0); + assertThat(wakeReasonTagsUnpooled).isGreaterThan(0); + } + private String toString(BatteryStats.HistoryItem item, boolean checkin) { StringWriter writer = new StringWriter(); PrintWriter pw = new PrintWriter(writer); - mHistoryPrinter.printNextItem(pw, item, 0, checkin, /* verbose */ true); + mHistoryPrinter.printNextItem(pw, item, 0, checkin, /* verbose */ false); pw.flush(); return writer.toString(); } |