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

Commit bfc3bb8d authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Use CursorWindow to hold BatteryConsumer data"

parents edea4d67 cadeaf8b
Loading
Loading
Loading
Loading
+21 −39
Original line number Diff line number Diff line
@@ -31,51 +31,33 @@ import java.io.PrintWriter;
 *
 * {@hide}
 */
public final class AggregateBatteryConsumer extends BatteryConsumer implements Parcelable {
public final class AggregateBatteryConsumer extends BatteryConsumer {
    static final int CONSUMER_TYPE_AGGREGATE = 0;

    private final double mConsumedPowerMah;
    static final int COLUMN_INDEX_SCOPE = BatteryConsumer.COLUMN_COUNT;
    static final int COLUMN_INDEX_CONSUMED_POWER = COLUMN_INDEX_SCOPE + 1;
    static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 2;

    public AggregateBatteryConsumer(@NonNull Builder builder) {
        super(builder.mPowerComponentsBuilder.build());
        mConsumedPowerMah = builder.mConsumedPowerMah;
    AggregateBatteryConsumer(BatteryConsumerData data) {
        super(data);
    }

    private AggregateBatteryConsumer(@NonNull Parcel source) {
        super(new PowerComponents(source));
        mConsumedPowerMah = source.readDouble();
    private AggregateBatteryConsumer(@NonNull Builder builder) {
        super(builder.mData, builder.mPowerComponentsBuilder.build());
    }

    @Override
    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
        mPowerComponents.dump(pw, skipEmptyComponents);
    int getScope() {
        return mData.getInt(COLUMN_INDEX_SCOPE);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeDouble(mConsumedPowerMah);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @NonNull
    public static final Creator<AggregateBatteryConsumer> CREATOR =
            new Creator<AggregateBatteryConsumer>() {
                public AggregateBatteryConsumer createFromParcel(@NonNull Parcel source) {
                    return new AggregateBatteryConsumer(source);
                }

                public AggregateBatteryConsumer[] newArray(int size) {
                    return new AggregateBatteryConsumer[size];
    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
        mPowerComponents.dump(pw, skipEmptyComponents);
    }
            };

    @Override
    public double getConsumedPower() {
        return mConsumedPowerMah;
        return mData.getDouble(COLUMN_INDEX_CONSUMED_POWER);
    }

    /** Serializes this object to XML */
@@ -83,7 +65,7 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
            @BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException {
        serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
        serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope);
        serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, mConsumedPowerMah);
        serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, getConsumedPower());
        mPowerComponents.writeToXml(serializer);
        serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
    }
@@ -119,17 +101,16 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
     * Builder for DeviceBatteryConsumer.
     */
    public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> {
        private double mConsumedPowerMah;

        public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels) {
            super(customPowerComponentNames, includePowerModels);
        public Builder(BatteryConsumer.BatteryConsumerData data, int scope) {
            super(data, CONSUMER_TYPE_AGGREGATE);
            data.putInt(COLUMN_INDEX_SCOPE, scope);
        }

        /**
         * Sets the total power included in this aggregate.
         */
        public Builder setConsumedPower(double consumedPowerMah) {
            mConsumedPowerMah = consumedPowerMah;
            mData.putDouble(COLUMN_INDEX_CONSUMED_POWER, consumedPowerMah);
            return this;
        }

@@ -137,7 +118,8 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
         * Adds power and usage duration from the supplied AggregateBatteryConsumer.
         */
        public void add(AggregateBatteryConsumer aggregateBatteryConsumer) {
            mConsumedPowerMah += aggregateBatteryConsumer.mConsumedPowerMah;
            setConsumedPower(mData.getDouble(COLUMN_INDEX_CONSUMED_POWER)
                    + aggregateBatteryConsumer.getConsumedPower());
            mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents);
        }

+159 −15
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.database.CursorWindow;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import java.io.PrintWriter;
@@ -32,6 +34,8 @@ import java.lang.annotation.RetentionPolicy;
 */
public abstract class BatteryConsumer {

    private static final String TAG = "BatteryConsumer";

    /**
     * Power usage component, describing the particular part of the system
     * responsible for power drain.
@@ -147,12 +151,22 @@ public abstract class BatteryConsumer {
     */
    public static final int POWER_MODEL_MEASURED_ENERGY = 2;

    static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0;
    static final int COLUMN_COUNT = 1;

    protected final BatteryConsumerData mData;
    protected final PowerComponents mPowerComponents;

    protected BatteryConsumer(@NonNull PowerComponents powerComponents) {
    protected BatteryConsumer(BatteryConsumerData data, @NonNull PowerComponents powerComponents) {
        mData = data;
        mPowerComponents = powerComponents;
    }

    public BatteryConsumer(BatteryConsumerData data) {
        mData = data;
        mPowerComponents = new PowerComponents(data);
    }

    /**
     * Total power consumed by this consumer, in mAh.
     */
@@ -192,11 +206,7 @@ public abstract class BatteryConsumer {
    }

    public int getCustomPowerComponentCount() {
        return mPowerComponents.getCustomPowerComponentCount();
    }

    void setCustomPowerComponentNames(String[] customPowerComponentNames) {
        mPowerComponents.setCustomPowerComponentNames(customPowerComponentNames);
        return mData.layout.customPowerComponentCount;
    }

    /**
@@ -231,10 +241,6 @@ public abstract class BatteryConsumer {
        return mPowerComponents.getUsageDurationForCustomComponentMillis(componentId);
    }

    protected void writeToParcel(Parcel dest, int flags) {
        mPowerComponents.writeToParcel(dest, flags);
    }

    /**
     * Returns the name of the specified component.  Intended for logging and debugging.
     */
@@ -318,15 +324,153 @@ public abstract class BatteryConsumer {
        return (long) (powerMah * (10 * 3600 / 1000) + 0.5);
    }

    protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
        final PowerComponents.Builder mPowerComponentsBuilder;
    static class BatteryConsumerData {
        private final CursorWindow mCursorWindow;
        private final int mCursorRow;
        public final BatteryConsumerDataLayout layout;

        BatteryConsumerData(CursorWindow cursorWindow, int cursorRow,
                BatteryConsumerDataLayout layout) {
            mCursorWindow = cursorWindow;
            mCursorRow = cursorRow;
            this.layout = layout;
        }

        @Nullable
        static BatteryConsumerData create(CursorWindow cursorWindow,
                BatteryConsumerDataLayout layout) {
            int cursorRow = cursorWindow.getNumRows();
            if (!cursorWindow.allocRow()) {
                Slog.e(TAG, "Cannot allocate BatteryConsumerData: too many UIDs: " + cursorRow);
                cursorRow = -1;
            }
            return new BatteryConsumerData(cursorWindow, cursorRow, layout);
        }

        void putInt(int columnIndex, int value) {
            if (mCursorRow == -1) {
                return;
            }
            mCursorWindow.putLong(value, mCursorRow, columnIndex);
        }

        int getInt(int columnIndex) {
            if (mCursorRow == -1) {
                return 0;
            }
            return mCursorWindow.getInt(mCursorRow, columnIndex);
        }

        void putDouble(int columnIndex, double value) {
            if (mCursorRow == -1) {
                return;
            }
            mCursorWindow.putDouble(value, mCursorRow, columnIndex);
        }

        double getDouble(int columnIndex) {
            if (mCursorRow == -1) {
                return 0;
            }
            return mCursorWindow.getDouble(mCursorRow, columnIndex);
        }

        void putLong(int columnIndex, long value) {
            if (mCursorRow == -1) {
                return;
            }
            mCursorWindow.putLong(value, mCursorRow, columnIndex);
        }

        public BaseBuilder(@NonNull String[] customPowerComponentNames,
                boolean includePowerModels) {
            mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentNames,
        long getLong(int columnIndex) {
            if (mCursorRow == -1) {
                return 0;
            }
            return mCursorWindow.getLong(mCursorRow, columnIndex);
        }

        void putString(int columnIndex, String value) {
            if (mCursorRow == -1) {
                return;
            }
            mCursorWindow.putString(value, mCursorRow, columnIndex);
        }

        String getString(int columnIndex) {
            if (mCursorRow == -1) {
                return null;
            }
            return mCursorWindow.getString(mCursorRow, columnIndex);
        }
    }

    static class BatteryConsumerDataLayout {
        public final String[] customPowerComponentNames;
        public final int customPowerComponentCount;
        public final boolean powerModelsIncluded;

        public final int consumedPowerColumn;
        public final int firstConsumedPowerColumn;
        public final int firstCustomConsumedPowerColumn;
        public final int firstUsageDurationColumn;
        public final int firstCustomUsageDurationColumn;
        public final int firstPowerModelColumn;
        public final int columnCount;

        private BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames,
                boolean powerModelsIncluded) {
            this.customPowerComponentNames = customPowerComponentNames;
            this.customPowerComponentCount = customPowerComponentNames.length;
            this.powerModelsIncluded = powerModelsIncluded;

            int columnIndex = firstColumn;
            consumedPowerColumn = columnIndex++;

            firstConsumedPowerColumn = columnIndex;
            columnIndex += BatteryConsumer.POWER_COMPONENT_COUNT;

            firstCustomConsumedPowerColumn = columnIndex;
            columnIndex += customPowerComponentCount;

            firstUsageDurationColumn = columnIndex;
            columnIndex += BatteryConsumer.POWER_COMPONENT_COUNT;

            firstCustomUsageDurationColumn = columnIndex;
            columnIndex += customPowerComponentCount;

            if (powerModelsIncluded) {
                firstPowerModelColumn = columnIndex;
                columnIndex += BatteryConsumer.POWER_COMPONENT_COUNT;
            } else {
                firstPowerModelColumn = -1;
            }

            columnCount = columnIndex;
        }
    }

    static BatteryConsumerDataLayout createBatteryConsumerDataLayout(
            String[] customPowerComponentNames, boolean includePowerModels) {
        int columnCount = BatteryConsumer.COLUMN_COUNT;
        columnCount = Math.max(columnCount, AggregateBatteryConsumer.COLUMN_COUNT);
        columnCount = Math.max(columnCount, UidBatteryConsumer.COLUMN_COUNT);
        columnCount = Math.max(columnCount, UserBatteryConsumer.COLUMN_COUNT);

        return new BatteryConsumerDataLayout(columnCount, customPowerComponentNames,
                includePowerModels);
    }

    protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
        protected final BatteryConsumer.BatteryConsumerData mData;
        protected final PowerComponents.Builder mPowerComponentsBuilder;

        public BaseBuilder(BatteryConsumer.BatteryConsumerData data, int consumerType) {
            mData = data;
            data.putLong(COLUMN_INDEX_BATTERY_CONSUMER_TYPE, consumerType);

            mPowerComponentsBuilder = new PowerComponents.Builder(data);
        }

        /**
         * Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
         *
+123 −61

File changed.

Preview size limit exceeded, changes collapsed.

+153 −213

File changed.

Preview size limit exceeded, changes collapsed.

+47 −70
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ import java.lang.annotation.RetentionPolicy;
 *
 * @hide
 */
public final class UidBatteryConsumer extends BatteryConsumer implements Parcelable {
public final class UidBatteryConsumer extends BatteryConsumer {

    static final int CONSUMER_TYPE_UID = 1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
@@ -66,19 +68,27 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
     */
    public static final int STATE_BACKGROUND = 1;

    private final int mUid;
    @Nullable
    private final String mPackageWithHighestDrain;
    private final long mTimeInForegroundMs;
    private final long mTimeInBackgroundMs;
    static final int COLUMN_INDEX_UID = BatteryConsumer.COLUMN_COUNT;
    static final int COLUMN_INDEX_PACKAGE_WITH_HIGHEST_DRAIN = COLUMN_INDEX_UID + 1;
    static final int COLUMN_INDEX_TIME_IN_FOREGROUND = COLUMN_INDEX_UID + 2;
    static final int COLUMN_INDEX_TIME_IN_BACKGROUND = COLUMN_INDEX_UID + 3;
    static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 4;

    UidBatteryConsumer(BatteryConsumerData data) {
        super(data);
    }

    private UidBatteryConsumer(@NonNull Builder builder) {
        super(builder.mData, builder.mPowerComponentsBuilder.build());
    }

    public int getUid() {
        return mUid;
        return mData.getInt(COLUMN_INDEX_UID);
    }

    @Nullable
    public String getPackageWithHighestDrain() {
        return mPackageWithHighestDrain;
        return mData.getString(COLUMN_INDEX_PACKAGE_WITH_HIGHEST_DRAIN);
    }

    /**
@@ -87,41 +97,13 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
    public long getTimeInStateMs(@State int state) {
        switch (state) {
            case STATE_BACKGROUND:
                return mTimeInBackgroundMs;
                return mData.getInt(COLUMN_INDEX_TIME_IN_BACKGROUND);
            case STATE_FOREGROUND:
                return mTimeInForegroundMs;
                return mData.getInt(COLUMN_INDEX_TIME_IN_FOREGROUND);
        }
        return 0;
    }

    private UidBatteryConsumer(@NonNull Builder builder) {
        super(builder.mPowerComponentsBuilder.build());
        mUid = builder.mUid;
        mPackageWithHighestDrain = builder.mPackageWithHighestDrain;
        mTimeInForegroundMs = builder.mTimeInForegroundMs;
        mTimeInBackgroundMs = builder.mTimeInBackgroundMs;
    }

    private UidBatteryConsumer(@NonNull Parcel source) {
        super(new PowerComponents(source));
        mUid = source.readInt();
        mPackageWithHighestDrain = source.readString();
        mTimeInForegroundMs = source.readLong();
        mTimeInBackgroundMs = source.readLong();
    }

    /**
     * Writes the contents into a Parcel.
     */
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(mUid);
        dest.writeString(mPackageWithHighestDrain);
        dest.writeLong(mTimeInForegroundMs);
        dest.writeLong(mTimeInBackgroundMs);
    }

    @Override
    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
        final double consumedPower = getConsumedPower();
@@ -134,20 +116,8 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
        pw.print(" ) ");
    }

    @NonNull
    public static final Creator<UidBatteryConsumer> CREATOR = new Creator<UidBatteryConsumer>() {
        public UidBatteryConsumer createFromParcel(@NonNull Parcel source) {
            return new UidBatteryConsumer(source);
        }

        public UidBatteryConsumer[] newArray(int size) {
            return new UidBatteryConsumer[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    static UidBatteryConsumer create(BatteryConsumerData data) {
        return new UidBatteryConsumer(data);
    }

    /** Serializes this object to XML */
@@ -158,14 +128,15 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela

        serializer.startTag(null, BatteryUsageStats.XML_TAG_UID);
        serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_UID, getUid());
        if (!TextUtils.isEmpty(mPackageWithHighestDrain)) {
        final String packageWithHighestDrain = getPackageWithHighestDrain();
        if (!TextUtils.isEmpty(packageWithHighestDrain)) {
            serializer.attribute(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE,
                    mPackageWithHighestDrain);
                    packageWithHighestDrain);
        }
        serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND,
                mTimeInForegroundMs);
                getTimeInStateMs(STATE_FOREGROUND));
        serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND,
                mTimeInBackgroundMs);
                getTimeInStateMs(STATE_BACKGROUND));
        mPowerComponents.writeToXml(serializer);
        serializer.endTag(null, BatteryUsageStats.XML_TAG_UID);
    }
@@ -209,22 +180,20 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
        private final BatteryStats.Uid mBatteryStatsUid;
        private final int mUid;
        private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED;
        public long mTimeInForegroundMs;
        public long mTimeInBackgroundMs;
        private boolean mExcludeFromBatteryUsageStats;

        public Builder(@NonNull String[] customPowerComponentNames,
                boolean includePowerModels, @NonNull BatteryStats.Uid batteryStatsUid) {
            super(customPowerComponentNames, includePowerModels);
        public Builder(BatteryConsumerData data, @NonNull BatteryStats.Uid batteryStatsUid) {
            super(data, CONSUMER_TYPE_UID);
            mBatteryStatsUid = batteryStatsUid;
            mUid = batteryStatsUid.getUid();
            data.putLong(COLUMN_INDEX_UID, mUid);
        }

        public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels,
                int uid) {
            super(customPowerComponentNames, includePowerModels);
        public Builder(BatteryConsumerData data, int uid) {
            super(data, CONSUMER_TYPE_UID);
            mBatteryStatsUid = null;
            mUid = uid;
            data.putLong(COLUMN_INDEX_UID, mUid);
        }

        @NonNull
@@ -258,10 +227,10 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
        public Builder setTimeInStateMs(@State int state, long timeInStateMs) {
            switch (state) {
                case STATE_FOREGROUND:
                    mTimeInForegroundMs = timeInStateMs;
                    mData.putLong(COLUMN_INDEX_TIME_IN_FOREGROUND, timeInStateMs);
                    break;
                case STATE_BACKGROUND:
                    mTimeInBackgroundMs = timeInStateMs;
                    mData.putLong(COLUMN_INDEX_TIME_IN_BACKGROUND, timeInStateMs);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported state: " + state);
@@ -282,13 +251,18 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
         */
        public Builder add(UidBatteryConsumer consumer) {
            mPowerComponentsBuilder.addPowerAndDuration(consumer.mPowerComponents);
            mTimeInBackgroundMs += consumer.mTimeInBackgroundMs;
            mTimeInForegroundMs += consumer.mTimeInForegroundMs;

            setTimeInStateMs(STATE_FOREGROUND,
                    mData.getLong(COLUMN_INDEX_TIME_IN_FOREGROUND)
                            + consumer.getTimeInStateMs(STATE_FOREGROUND));
            setTimeInStateMs(STATE_BACKGROUND,
                    mData.getLong(COLUMN_INDEX_TIME_IN_BACKGROUND)
                            + consumer.getTimeInStateMs(STATE_BACKGROUND));

            if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
                mPackageWithHighestDrain = consumer.mPackageWithHighestDrain;
                mPackageWithHighestDrain = consumer.getPackageWithHighestDrain();
            } else if (!TextUtils.equals(mPackageWithHighestDrain,
                    consumer.mPackageWithHighestDrain)) {
                    consumer.getPackageWithHighestDrain())) {
                // Consider combining two UidBatteryConsumers with this distribution
                // of power drain between packages:
                // (package1=100, package2=10) and (package1=100, package2=101).
@@ -317,6 +291,9 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
            if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
                mPackageWithHighestDrain = null;
            }
            if (mPackageWithHighestDrain != null) {
                mData.putString(COLUMN_INDEX_PACKAGE_WITH_HIGHEST_DRAIN, mPackageWithHighestDrain);
            }
            return new UidBatteryConsumer(this);
        }
    }
Loading