Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6489fbf5 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Include the history tag string in checkin file verbatim

This is done when the history tag pool overflows - otherwise
the tag wouldn't be included in the output at all.

Bug: 274242119
Bug: 300513898
Test: PowerStatsTests:BatteryStatsHistoryTest
Change-Id: I68cf65dd5285864bbf38115321da944d95c7438d
Merged-In: I68cf65dd5285864bbf38115321da944d95c7438d
(cherry picked from commit 49fa85a1)
parent c78ab05e
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -1655,6 +1655,8 @@ public abstract class BatteryStats {
    public abstract long[] getCpuFreqs();

    public final static class HistoryTag {
        public static final int HISTORY_TAG_POOL_OVERFLOW = -1;

        public String string;
        public int uid;

@@ -6786,10 +6788,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);
@@ -6809,7 +6812,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);
@@ -7070,7 +7073,14 @@ public abstract class BatteryStats {
                if (rec.wakeReasonTag != null) {
                    if (checkin) {
                        item.append(",wr=");
                        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);
@@ -7098,7 +7108,15 @@ public abstract class BatteryStats {
                    }
                    item.append("=");
                    if (checkin) {
                        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));
+2 −1
Original line number Diff line number Diff line
@@ -178,7 +178,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<>();
@@ -1848,6 +1848,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;
        }
+5 −1
Original line number Diff line number Diff line
@@ -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;
            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 {
+89 −3
Original line number Diff line number Diff line
@@ -37,7 +37,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;
@@ -64,8 +63,9 @@ 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
    private BatteryStatsHistory.TraceDelegate mTracer;
    @Mock
@@ -89,6 +89,8 @@ public class BatteryStatsHistoryTest {

        when(mStepDetailsCalculator.getHistoryStepDetails())
                .thenReturn(new BatteryStats.HistoryStepDetails());

        mHistoryPrinter = new BatteryStats.HistoryPrinter();
    }

    @Test
@@ -366,11 +368,95 @@ public class BatteryStatsHistoryTest {
        assertThat(checkin).contains("XC,10321,400,500,600");
    }

    @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) {
        BatteryStats.HistoryPrinter printer = new BatteryStats.HistoryPrinter();
        StringWriter writer = new StringWriter();
        PrintWriter pw = new PrintWriter(writer);
        printer.printNextItem(pw, item, 0, checkin, /* verbose */ true);
        mHistoryPrinter.printNextItem(pw, item, 0, checkin, /* verbose */ false);
        pw.flush();
        return writer.toString();
    }