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

Commit 0c2a3a82 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Add EnergyConsumer data to battery history

Bug: 243199649
Test: atest FrameworksServicesTests:BatteryStatsTests

Change-Id: I9ed353dc313a01995d0de96415336dd5298e4aa0
parent a230afa8
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
@@ -1766,6 +1766,49 @@ public abstract class BatteryStats {
        }
    }

    /**
     * Measured energy delta from the previous reading.
     */
    public static final class MeasuredEnergyDetails {
        /**
         * Description of the energy consumer, such as CPU, DISPLAY etc
         */
        public static final class EnergyConsumer {
            /**
             * See android.hardware.power.stats.EnergyConsumerType
             */
            public int type;
            /**
             * Used when there are multipe energy consumers of the same type, such
             * as CPU clusters, multiple displays on foldable devices etc.
             */
            public int ordinal;
            /**
             * Human-readable name of the energy consumer, e.g. "CPU"
             */
            public String name;
        }
        public EnergyConsumer[] consumers;
        public long[] chargeUC;

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < consumers.length; i++) {
                if (chargeUC[i] == POWER_DATA_UNAVAILABLE) {
                    continue;
                }
                if (sb.length() != 0) {
                    sb.append(' ');
                }
                sb.append(consumers[i].name);
                sb.append('=');
                sb.append(chargeUC[i]);
            }
            return sb.toString();
        }
    }

    /**
     * Battery history record.
     */
@@ -1886,6 +1929,7 @@ public abstract class BatteryStats {
        public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
        public static final int STATE2_CELLULAR_HIGH_TX_POWER_FLAG = 1 << 19;
        public static final int STATE2_USB_DATA_LINK_FLAG = 1 << 18;
        public static final int STATE2_EXTENSIONS_FLAG = 1 << 17;

        public static final int MOST_INTERESTING_STATES2 =
                STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
@@ -1905,6 +1949,9 @@ public abstract class BatteryStats {
        // Non-null when there is more detailed information at this step.
        public HistoryStepDetails stepDetails;

        // Non-null when there is measured energy information
        public MeasuredEnergyDetails measuredEnergyDetails;

        public static final int EVENT_FLAG_START = 0x8000;
        public static final int EVENT_FLAG_FINISH = 0x4000;

@@ -2113,6 +2160,7 @@ public abstract class BatteryStats {
            eventCode = EVENT_NONE;
            eventTag = null;
            tagsFirstOccurrence = false;
            measuredEnergyDetails = null;
        }

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
@@ -2162,6 +2210,7 @@ public abstract class BatteryStats {
            }
            tagsFirstOccurrence = o.tagsFirstOccurrence;
            currentTime = o.currentTime;
            measuredEnergyDetails = o.measuredEnergyDetails;
        }

        public boolean sameNonEvent(HistoryItem o) {
@@ -6951,6 +7000,14 @@ public abstract class BatteryStats {
                        item.append("\"");
                    }
                }
                if ((rec.states2 & HistoryItem.STATE2_EXTENSIONS_FLAG) != 0) {
                    if (!checkin) {
                        item.append(" ext=");
                        if (rec.measuredEnergyDetails != null) {
                            item.append("E");
                        }
                    }
                }
                if (rec.eventCode != HistoryItem.EVENT_NONE) {
                    item.append(checkin ? "," : " ");
                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
@@ -7075,6 +7132,25 @@ public abstract class BatteryStats {
                        item.append("\n");
                    }
                }
                if (rec.measuredEnergyDetails != null) {
                    if (!checkin) {
                        item.append("                 Energy: ");
                        item.append(rec.measuredEnergyDetails);
                        item.append("\n");
                    } else {
                        item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
                        item.append(HISTORY_DATA); item.append(",0,XE");
                        for (int i = 0; i < rec.measuredEnergyDetails.consumers.length; i++) {
                            if (rec.measuredEnergyDetails.chargeUC[i] != POWER_DATA_UNAVAILABLE) {
                                item.append(',');
                                item.append(rec.measuredEnergyDetails.consumers[i].name);
                                item.append('=');
                                item.append(rec.measuredEnergyDetails.chargeUC[i]);
                            }
                        }
                        item.append("\n");
                    }
                }
                oldState = rec.states;
                oldState2 = rec.states2;
                // Clear High Tx Power Flag for volta positioning
+49 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.BatteryManager;
import android.os.BatteryStats.HistoryItem;
import android.os.BatteryStats.HistoryStepDetails;
import android.os.BatteryStats.HistoryTag;
import android.os.BatteryStats.MeasuredEnergyDetails;
import android.os.Parcel;
import android.os.ParcelFormatException;
import android.os.Process;
@@ -113,6 +114,9 @@ public class BatteryStatsHistory {
    // therefore the tag value is written in the parcel
    static final int TAG_FIRST_OCCURRENCE_FLAG = 0x8000;

    static final int EXTENSION_MEASURED_ENERGY_HEADER_FLAG = 0x00000001;
    static final int EXTENSION_MEASURED_ENERGY_FLAG = 0x00000002;

    private final Parcel mHistoryBuffer;
    private final File mSystemDir;
    private final HistoryStepDetailsCalculator mStepDetailsCalculator;
@@ -183,6 +187,7 @@ public class BatteryStatsHistory {
    private long mTrackRunningHistoryElapsedRealtimeMs = 0;
    private long mTrackRunningHistoryUptimeMs = 0;
    private long mHistoryBaseTimeMs;
    private boolean mMeasuredEnergyHeaderWritten = false;

    private byte mLastHistoryStepLevel = 0;

@@ -293,6 +298,7 @@ public class BatteryStatsHistory {
        mLastHistoryElapsedRealtimeMs = 0;
        mTrackRunningHistoryElapsedRealtimeMs = 0;
        mTrackRunningHistoryUptimeMs = 0;
        mMeasuredEnergyHeaderWritten = false;

        mHistoryBuffer.setDataSize(0);
        mHistoryBuffer.setDataPosition(0);
@@ -932,6 +938,16 @@ public class BatteryStatsHistory {
        writeHistoryItem(elapsedRealtimeMs, uptimeMs);
    }

    /**
     * Records measured energy data.
     */
    public void recordMeasuredEnergyDetails(long elapsedRealtimeMs, long uptimeMs,
            MeasuredEnergyDetails measuredEnergyDetails) {
        mHistoryCur.measuredEnergyDetails = measuredEnergyDetails;
        mHistoryCur.states2 |= HistoryItem.STATE2_EXTENSIONS_FLAG;
        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.
@@ -1256,6 +1272,7 @@ public class BatteryStatsHistory {
        cur.eventCode = HistoryItem.EVENT_NONE;
        cur.eventTag = null;
        cur.tagsFirstOccurrence = false;
        cur.measuredEnergyDetails = null;
        if (DEBUG) {
            Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
                    + " now " + mHistoryBuffer.dataPosition()
@@ -1348,6 +1365,7 @@ public class BatteryStatsHistory {
            return;
        }

        int extensionFlags = 0;
        final long deltaTime = cur.time - last.time;
        final int lastBatteryLevelInt = buildBatteryLevelInt(last);
        final int lastStateInt = buildStateInt(last);
@@ -1374,6 +1392,15 @@ public class BatteryStatsHistory {
        if (stateIntChanged) {
            firstToken |= BatteryStatsHistory.DELTA_STATE_FLAG;
        }
        if (cur.measuredEnergyDetails != null) {
            extensionFlags |= BatteryStatsHistory.EXTENSION_MEASURED_ENERGY_FLAG;
            if (!mMeasuredEnergyHeaderWritten) {
                extensionFlags |= BatteryStatsHistory.EXTENSION_MEASURED_ENERGY_HEADER_FLAG;
            }
        }
        if (extensionFlags != 0) {
            cur.states2 |= HistoryItem.STATE2_EXTENSIONS_FLAG;
        }
        final boolean state2IntChanged = cur.states2 != last.states2;
        if (state2IntChanged) {
            firstToken |= BatteryStatsHistory.DELTA_STATE2_FLAG;
@@ -1491,6 +1518,28 @@ public class BatteryStatsHistory {
        }
        dest.writeDouble(cur.modemRailChargeMah);
        dest.writeDouble(cur.wifiRailChargeMah);
        if (extensionFlags != 0) {
            dest.writeInt(extensionFlags);
            if (cur.measuredEnergyDetails != null) {
                if (DEBUG) {
                    Slog.i(TAG, "WRITE DELTA: measuredEnergyDetails=" + cur.measuredEnergyDetails);
                }
                if (!mMeasuredEnergyHeaderWritten) {
                    MeasuredEnergyDetails.EnergyConsumer[] consumers =
                            cur.measuredEnergyDetails.consumers;
                    dest.writeInt(consumers.length);
                    for (MeasuredEnergyDetails.EnergyConsumer consumer : consumers) {
                        dest.writeInt(consumer.type);
                        dest.writeInt(consumer.ordinal);
                        dest.writeString(consumer.name);
                    }
                    mMeasuredEnergyHeaderWritten = true;
                }
                for (long chargeUC : cur.measuredEnergyDetails.chargeUC) {
                    dest.writeLong(chargeUC);
                }
            }
        }
    }

    private int buildBatteryLevelInt(HistoryItem h) {
+35 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ public class BatteryStatsHistoryIterator {
    private final BatteryStats.HistoryStepDetails mReadHistoryStepDetails =
            new BatteryStats.HistoryStepDetails();
    private final SparseArray<BatteryStats.HistoryTag> mHistoryTags = new SparseArray<>();
    private BatteryStats.MeasuredEnergyDetails mMeasuredEnergyDetails;

    public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history) {
        mBatteryStatsHistory = history;
@@ -198,6 +199,40 @@ public class BatteryStatsHistoryIterator {
        }
        cur.modemRailChargeMah = src.readDouble();
        cur.wifiRailChargeMah = src.readDouble();
        if ((cur.states2 & BatteryStats.HistoryItem.STATE2_EXTENSIONS_FLAG) != 0) {
            final int extensionFlags = src.readInt();
            if ((extensionFlags & BatteryStatsHistory.EXTENSION_MEASURED_ENERGY_HEADER_FLAG) != 0) {
                if (mMeasuredEnergyDetails == null) {
                    mMeasuredEnergyDetails = new BatteryStats.MeasuredEnergyDetails();
                }

                final int consumerCount = src.readInt();
                mMeasuredEnergyDetails.consumers =
                        new BatteryStats.MeasuredEnergyDetails.EnergyConsumer[consumerCount];
                mMeasuredEnergyDetails.chargeUC = new long[consumerCount];
                for (int i = 0; i < consumerCount; i++) {
                    BatteryStats.MeasuredEnergyDetails.EnergyConsumer consumer =
                            new BatteryStats.MeasuredEnergyDetails.EnergyConsumer();
                    consumer.type = src.readInt();
                    consumer.ordinal = src.readInt();
                    consumer.name = src.readString();
                    mMeasuredEnergyDetails.consumers[i] = consumer;
                }
            }

            if ((extensionFlags & BatteryStatsHistory.EXTENSION_MEASURED_ENERGY_FLAG) != 0) {
                if (mMeasuredEnergyDetails == null) {
                    throw new IllegalStateException("MeasuredEnergyDetails without a header");
                }

                for (int i = 0; i < mMeasuredEnergyDetails.chargeUC.length; i++) {
                    mMeasuredEnergyDetails.chargeUC[i] = src.readLong();
                }
                cur.measuredEnergyDetails = mMeasuredEnergyDetails;
            }
        } else {
            cur.measuredEnergyDetails = null;
        }
    }

    private boolean readHistoryTag(Parcel src, int index, BatteryStats.HistoryTag outTag) {
+5 −0
Original line number Diff line number Diff line
@@ -663,6 +663,11 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
                    BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS,
                    reason, 0);

            if (measuredEnergyDeltas != null && !measuredEnergyDeltas.isEmpty()) {
                mStats.recordMeasuredEnergyDetailsLocked(elapsedRealtime, uptime,
                        mMeasuredEnergySnapshot.getMeasuredEnergyDetails(measuredEnergyDeltas));
            }

            if ((updateFlags & UPDATE_CPU) != 0) {
                if (useLatestStates) {
                    onBattery = mStats.isOnBatteryLocked();
+10 −0
Original line number Diff line number Diff line
@@ -7404,6 +7404,16 @@ public class BatteryStatsImpl extends BatteryStats {
        return names;
    }
    /**
     * Adds measured energy delta to battery history.
     */
    @GuardedBy("this")
    public void recordMeasuredEnergyDetailsLocked(long elapsedRealtimeMs,
            long uptimeMs, MeasuredEnergyDetails measuredEnergyDetails) {
        mHistory.recordMeasuredEnergyDetails(elapsedRealtimeMs, uptimeMs,
                measuredEnergyDetails);
    }
    @GuardedBy("this")
    @Override public long getStartClockTime() {
        final long currentTimeMs = mClock.currentTimeMillis();
Loading