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

Commit d292f83b authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Remove support for PowerModel

This significantly reduces the native memory allocation
for BatteryUsageStats

Bug: 377583773
Test: atest PowerStatsTests; atest PowerStatsTestsRavenwood
Flag: EXEMPT bugfix
Change-Id: If136858f5b8db47b748f137840d63163083737bc
parent 320b9e02
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.os;

import android.annotation.NonNull;
import android.util.proto.ProtoOutputStream;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -100,19 +99,6 @@ public final class AggregateBatteryConsumer extends BatteryConsumer {
        }
    }

    void writePowerComponentModelProto(@NonNull ProtoOutputStream proto) {
        for (int i = 0; i < POWER_COMPONENT_COUNT; i++) {
            final int powerModel = getPowerModel(i);
            if (powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) continue;

            final long token = proto.start(BatteryUsageStatsAtomsProto.COMPONENT_MODELS);
            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.COMPONENT, i);
            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_MODEL,
                    powerModelToProtoEnum(powerModel));
            proto.end(token);
        }
    }

    /**
     * Builder for DeviceBatteryConsumer.
     */
+29 −51
Original line number Diff line number Diff line
@@ -161,18 +161,27 @@ public abstract class BatteryConsumer {

    /**
     * Unspecified power model.
     *
     * @deprecated PowerModel is no longer supported
     */
    @Deprecated
    public static final int POWER_MODEL_UNDEFINED = 0;

    /**
     * Power model that is based on average consumption rates that hardware components
     * consume in various states.
     *
     * @deprecated PowerModel is no longer supported
     */
    @Deprecated
    public static final int POWER_MODEL_POWER_PROFILE = 1;

    /**
     * Power model that is based on energy consumption stats provided by PowerStats HAL.
     *
     * @deprecated PowerModel is no longer supported
     */
    @Deprecated
    public static final int POWER_MODEL_ENERGY_CONSUMPTION = 2;

    /**
@@ -380,19 +389,17 @@ public abstract class BatteryConsumer {
        public final @ScreenState int screenState;
        public final @PowerState int powerState;

        final int mPowerModelColumnIndex;
        final int mPowerColumnIndex;
        final int mDurationColumnIndex;

        private Key(@PowerComponentId int powerComponentId, @ProcessState int processState,
                @ScreenState int screenState, @PowerState int powerState, int powerModelColumnIndex,
                @ScreenState int screenState, @PowerState int powerState,
                int powerColumnIndex, int durationColumnIndex) {
            this.powerComponentId = powerComponentId;
            this.processState = processState;
            this.screenState = screenState;
            this.powerState = powerState;

            mPowerModelColumnIndex = powerModelColumnIndex;
            mPowerColumnIndex = powerColumnIndex;
            mDurationColumnIndex = durationColumnIndex;
        }
@@ -577,11 +584,11 @@ public abstract class BatteryConsumer {
     *
     * @param componentId The ID of the power component, e.g.
     *                    {@link BatteryConsumer#POWER_COMPONENT_CPU}.
     * @deprecated PowerModel is no longer supported
     */
    @Deprecated
    public @PowerModel int getPowerModel(@PowerComponentId int componentId) {
        return mPowerComponents.getPowerModel(
                mData.layout.getKeyOrThrow(componentId, PROCESS_STATE_UNSPECIFIED,
                        SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED));
        return POWER_MODEL_UNDEFINED;
    }

    /**
@@ -589,9 +596,11 @@ public abstract class BatteryConsumer {
     *
     * @param key The key of the power component, obtained by calling {@link #getKey} or
     *            {@link #getKeys} method.
     * @deprecated PowerModel is no longer supported
     */
    @Deprecated
    public @PowerModel int getPowerModel(@NonNull BatteryConsumer.Key key) {
        return mPowerComponents.getPowerModel(key);
        return POWER_MODEL_UNDEFINED;
    }

    /**
@@ -656,20 +665,6 @@ public abstract class BatteryConsumer {
        return sPowerComponentNames[componentId];
    }

    /**
     * Returns the name of the specified power model.  Intended for logging and debugging.
     */
    public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) {
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION:
                return "energy consumption";
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
                return "power profile";
            default:
                return "";
        }
    }

    /**
     * Returns the equivalent PowerModel enum for the specified power model.
     * {@see BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage.PowerModel}
@@ -857,10 +852,8 @@ public abstract class BatteryConsumer {

    static class BatteryConsumerDataLayout {
        private static final Key[] KEY_ARRAY = new Key[0];
        public static final int POWER_MODEL_NOT_INCLUDED = -1;
        public final String[] customPowerComponentNames;
        public final int customPowerComponentCount;
        public final boolean powerModelsIncluded;
        public final boolean processStateDataIncluded;
        public final boolean screenStateDataIncluded;
        public final boolean powerStateDataIncluded;
@@ -872,11 +865,10 @@ public abstract class BatteryConsumer {
        private SparseArray<Key[]> mPerComponentKeys;

        private BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames,
                boolean powerModelsIncluded, boolean includeProcessStateData,
                boolean includeScreenState, boolean includePowerState) {
                boolean includeProcessStateData, boolean includeScreenState,
                boolean includePowerState) {
            this.customPowerComponentNames = customPowerComponentNames;
            this.customPowerComponentCount = customPowerComponentNames.length;
            this.powerModelsIncluded = powerModelsIncluded;
            this.processStateDataIncluded = includeProcessStateData;
            this.screenStateDataIncluded = includeScreenState;
            this.powerStateDataIncluded = includePowerState;
@@ -904,7 +896,7 @@ public abstract class BatteryConsumer {
                        continue;
                    }
                    for (int i = 0; i < powerComponentIds.length; i++) {
                        columnIndex = addKeys(keyList, powerModelsIncluded, includeProcessStateData,
                        columnIndex = addKeys(keyList, includeProcessStateData,
                                powerComponentIds[i], screenState, powerState, columnIndex);
                    }
                }
@@ -934,13 +926,10 @@ public abstract class BatteryConsumer {
            }
        }

        private int addKeys(List<Key> keys, boolean powerModelsIncluded,
                boolean includeProcessStateData, @PowerComponentId int componentId,
                int screenState, int powerState, int columnIndex) {
        private int addKeys(List<Key> keys, boolean includeProcessStateData,
                @PowerComponentId int componentId, int screenState, int powerState,
                int columnIndex) {
            keys.add(new Key(componentId, PROCESS_STATE_UNSPECIFIED, screenState, powerState,
                    powerModelsIncluded
                            ? columnIndex++
                            : POWER_MODEL_NOT_INCLUDED,  // power model
                    columnIndex++,      // power
                    columnIndex++       // usage duration
            ));
@@ -956,9 +945,6 @@ public abstract class BatteryConsumer {
                            continue;
                        }
                        keys.add(new Key(componentId, processState, screenState, powerState,
                                powerModelsIncluded
                                        ? columnIndex++
                                        : POWER_MODEL_NOT_INCLUDED, // power model
                                columnIndex++,      // power
                                columnIndex++       // usage duration
                        ));
@@ -1016,7 +1002,7 @@ public abstract class BatteryConsumer {
    }

    static BatteryConsumerDataLayout createBatteryConsumerDataLayout(
            String[] customPowerComponentNames, boolean includePowerModels,
            String[] customPowerComponentNames,
            boolean includeProcessStateData, boolean includeScreenStateData,
            boolean includePowerStateData) {
        int columnCount = BatteryConsumer.COLUMN_COUNT;
@@ -1025,8 +1011,7 @@ public abstract class BatteryConsumer {
        columnCount = Math.max(columnCount, UserBatteryConsumer.COLUMN_COUNT);

        return new BatteryConsumerDataLayout(columnCount, customPowerComponentNames,
                includePowerModels, includeProcessStateData, includeScreenStateData,
                includePowerStateData);
                includeProcessStateData, includeScreenStateData, includePowerStateData);
    }

    protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
@@ -1086,7 +1071,7 @@ public abstract class BatteryConsumer {
        public T setConsumedPower(@PowerComponentId int componentId, double componentPower,
                @PowerModel int powerModel) {
            mPowerComponentsBuilder.setConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
                    componentPower, powerModel);
                    componentPower);
            return (T) this;
        }

@@ -1095,14 +1080,14 @@ public abstract class BatteryConsumer {
        public T addConsumedPower(@PowerComponentId int componentId, double componentPower,
                @PowerModel int powerModel) {
            mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
                    componentPower, powerModel);
                    componentPower);
            return (T) this;
        }

        @SuppressWarnings("unchecked")
        @NonNull
        public T setConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
            mPowerComponentsBuilder.setConsumedPower(key, componentPower, powerModel);
            mPowerComponentsBuilder.setConsumedPower(key, componentPower);
            return (T) this;
        }

@@ -1110,21 +1095,14 @@ public abstract class BatteryConsumer {
        @NonNull
        public T addConsumedPower(@PowerComponentId int componentId, double componentPower) {
            mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
                    componentPower, POWER_MODEL_UNDEFINED);
                    componentPower);
            return (T) this;
        }

        @SuppressWarnings("unchecked")
        @NonNull
        public T addConsumedPower(Key key, double componentPower) {
            mPowerComponentsBuilder.addConsumedPower(key, componentPower, POWER_MODEL_UNDEFINED);
            return (T) this;
        }

        @SuppressWarnings("unchecked")
        @NonNull
        public T addConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
            mPowerComponentsBuilder.addConsumedPower(key, componentPower, powerModel);
            mPowerComponentsBuilder.addConsumedPower(key, componentPower);
            return (T) this;
        }

+7 −25
Original line number Diff line number Diff line
@@ -114,7 +114,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    static final String XML_ATTR_POWER_STATE = "power_state";
    static final String XML_ATTR_POWER = "power";
    static final String XML_ATTR_DURATION = "duration";
    static final String XML_ATTR_MODEL = "model";
    static final String XML_ATTR_BATTERY_CAPACITY = "battery_capacity";
    static final String XML_ATTR_DISCHARGE_PERCENT = "discharge_pct";
    static final String XML_ATTR_DISCHARGE_LOWER = "discharge_lower";
@@ -155,7 +154,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    private final long mBatteryTimeRemainingMs;
    private final long mChargeTimeRemainingMs;
    private final String[] mCustomPowerComponentNames;
    private final boolean mIncludesPowerModels;
    private final boolean mIncludesProcessStateData;
    private final boolean mIncludesScreenStateData;
    private final boolean mIncludesPowerStateData;
@@ -179,7 +177,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
        mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs;
        mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
        mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
        mIncludesPowerModels = builder.mIncludePowerModels;
        mIncludesProcessStateData = builder.mIncludesProcessStateData;
        mIncludesScreenStateData = builder.mIncludesScreenStateData;
        mIncludesPowerStateData = builder.mIncludesPowerStateData;
@@ -364,14 +361,13 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
        mBatteryTimeRemainingMs = source.readLong();
        mChargeTimeRemainingMs = source.readLong();
        mCustomPowerComponentNames = source.readStringArray();
        mIncludesPowerModels = source.readBoolean();
        mIncludesProcessStateData = source.readBoolean();
        mIncludesScreenStateData = source.readBoolean();
        mIncludesPowerStateData = source.readBoolean();

        mBatteryConsumersCursorWindow = CursorWindow.newFromParcel(source);
        mBatteryConsumerDataLayout = BatteryConsumer.createBatteryConsumerDataLayout(
                mCustomPowerComponentNames, mIncludesPowerModels, mIncludesProcessStateData,
                mCustomPowerComponentNames, mIncludesProcessStateData,
                mIncludesScreenStateData, mIncludesPowerStateData);

        final int numRows = mBatteryConsumersCursorWindow.getNumRows();
@@ -424,7 +420,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
        dest.writeLong(mBatteryTimeRemainingMs);
        dest.writeLong(mChargeTimeRemainingMs);
        dest.writeStringArray(mCustomPowerComponentNames);
        dest.writeBoolean(mIncludesPowerModels);
        dest.writeBoolean(mIncludesProcessStateData);
        dest.writeBoolean(mIncludesScreenStateData);
        dest.writeBoolean(mIncludesPowerStateData);
@@ -506,9 +501,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
                getDischargeDurationMs());
        deviceBatteryConsumer.writeStatsProto(proto,
                BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
        if (mIncludesPowerModels) {
            deviceBatteryConsumer.writePowerComponentModelProto(proto);
        }
        writeUidBatteryConsumersProto(proto, maxRawSize);
    }

@@ -629,7 +621,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {

            printPowerComponent(pw, prefix,
                    mBatteryConsumerDataLayout.getPowerComponentName(powerComponent),
                    devicePowerMah, appsPowerMah, BatteryConsumer.POWER_MODEL_UNDEFINED,
                    devicePowerMah, appsPowerMah,
                    deviceConsumer.getUsageDurationMillis(powerComponent));
        }

@@ -716,23 +708,15 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
            printPowerComponent(pw, prefix,
                    mBatteryConsumerDataLayout.getPowerComponentName(powerComponent),
                    devicePowerMah, appsPowerMah,
                    mIncludesPowerModels ? deviceConsumer.getPowerModel(powerComponent)
                            : BatteryConsumer.POWER_MODEL_UNDEFINED,
                    deviceConsumer.getUsageDurationMillis(dimensions));
        }
    }

    private void printPowerComponent(PrintWriter pw, String prefix, String label,
            double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) {
            double devicePowerMah, double appsPowerMah, long durationMs) {
        StringBuilder sb = new StringBuilder();
        sb.append(prefix).append("    ").append(label).append(": ")
                .append(BatteryStats.formatCharge(devicePowerMah));
        if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED
                && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
            sb.append(" [");
            sb.append(BatteryConsumer.powerModelToString(powerModel));
            sb.append("]");
        }
        sb.append(" apps: ").append(BatteryStats.formatCharge(appsPowerMah));
        if (durationMs != 0) {
            sb.append(" duration: ");
@@ -828,7 +812,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
                final boolean includesPowerStateData = parser.getAttributeBoolean(null,
                        XML_ATTR_PREFIX_INCLUDES_POWER_STATE_DATA, false);

                builder = new Builder(customComponentNames.toArray(new String[0]), true,
                builder = new Builder(customComponentNames.toArray(new String[0]),
                        includesProcStateData, includesScreenStateData, includesPowerStateData, 0);

                builder.setStatsStartTimestamp(
@@ -913,7 +897,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
        private final CursorWindow mBatteryConsumersCursorWindow;
        @NonNull
        private final String[] mCustomPowerComponentNames;
        private final boolean mIncludePowerModels;
        private final boolean mIncludesProcessStateData;
        private final boolean mIncludesScreenStateData;
        private final boolean mIncludesPowerStateData;
@@ -938,22 +921,21 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
        private BatteryStatsHistory mBatteryStatsHistory;

        public Builder(@NonNull String[] customPowerComponentNames) {
            this(customPowerComponentNames, false, false, false, false, 0);
            this(customPowerComponentNames, false, false, false, 0);
        }

        public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels,
        public Builder(@NonNull String[] customPowerComponentNames,
                boolean includeProcessStateData, boolean includeScreenStateData,
                boolean includesPowerStateData, double minConsumedPowerThreshold) {
            mBatteryConsumersCursorWindow =
                    new CursorWindow(null, BATTERY_CONSUMER_CURSOR_WINDOW_SIZE);
            onCursorWindowAllocated(mBatteryConsumersCursorWindow);
            mBatteryConsumerDataLayout = BatteryConsumer.createBatteryConsumerDataLayout(
                    customPowerComponentNames, includePowerModels, includeProcessStateData,
                    customPowerComponentNames, includeProcessStateData,
                    includeScreenStateData, includesPowerStateData);
            mBatteryConsumersCursorWindow.setNumColumns(mBatteryConsumerDataLayout.columnCount);

            mCustomPowerComponentNames = customPowerComponentNames;
            mIncludePowerModels = includePowerModels;
            mIncludesProcessStateData = includeProcessStateData;
            mIncludesScreenStateData = includeScreenStateData;
            mIncludesPowerStateData = includesPowerStateData;
+5 −7
Original line number Diff line number Diff line
@@ -65,12 +65,6 @@ public final class BatteryUsageStatsQuery implements Parcelable {
     */
    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 0x0002;

    /**
     * Indicates that identifiers of power models used for computations of power
     * consumption should be included in the BatteryUsageStats.
     */
    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS = 0x0004;

    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA = 0x0008;

    public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS = 0x0010;
@@ -311,7 +305,10 @@ public final class BatteryUsageStatsQuery implements Parcelable {
         * power monitoring data is available.
         *
         * Should only be used for testing and debugging.
         *
         * @deprecated PowerModel is no longer supported
         */
        @Deprecated
        public Builder powerProfileModeledOnly() {
            mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL;
            return this;
@@ -322,9 +319,10 @@ public final class BatteryUsageStatsQuery implements Parcelable {
         * of power consumption.
         *
         * Should only be used for testing and debugging.
         * @deprecated PowerModel is no longer supported
         */
        @Deprecated
        public Builder includePowerModels() {
            mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS;
            return this;
        }

+4 −66
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
 */
package android.os;

import static android.os.BatteryConsumer.BatteryConsumerDataLayout.POWER_MODEL_NOT_INCLUDED;
import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
import static android.os.BatteryConsumer.POWER_COMPONENT_BASE;
import static android.os.BatteryConsumer.POWER_STATE_ANY;
@@ -156,15 +155,6 @@ class PowerComponents {
        return mData.layout.getPowerComponentName(componentId);
    }

    @BatteryConsumer.PowerModel
    int getPowerModel(BatteryConsumer.Key key) {
        if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
            throw new IllegalStateException(
                    "Power model IDs were not requested in the BatteryUsageStatsQuery");
        }
        return mData.getInt(key.mPowerModelColumnIndex);
    }

    /**
     * Returns the amount of time used by the specified component, e.g. CPU, WiFi etc.
     *
@@ -378,10 +368,6 @@ class PowerComponents {
            if (durationMs != 0) {
                serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
            }
            if (mData.layout.powerModelsIncluded) {
                serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_MODEL,
                        getPowerModel(key));
            }
            serializer.endTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
        }
        serializer.endTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
@@ -411,7 +397,6 @@ class PowerComponents {
                        int powerState = POWER_STATE_UNSPECIFIED;
                        double powerMah = 0;
                        long durationMs = 0;
                        int model = BatteryConsumer.POWER_MODEL_UNDEFINED;
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            switch (parser.getAttributeName(i)) {
                                case BatteryUsageStats.XML_ATTR_ID:
@@ -432,14 +417,11 @@ class PowerComponents {
                                case BatteryUsageStats.XML_ATTR_DURATION:
                                    durationMs = parser.getAttributeLong(i);
                                    break;
                                case BatteryUsageStats.XML_ATTR_MODEL:
                                    model = parser.getAttributeInt(i);
                                    break;
                            }
                        }
                        final BatteryConsumer.Key key = builder.mData.layout.getKey(componentId,
                                processState, screenState, powerState);
                        builder.addConsumedPower(key, powerMah, model);
                        builder.addConsumedPower(key, powerMah);
                        builder.addUsageDurationMillis(key, durationMs);
                        break;
                    }
@@ -453,43 +435,28 @@ class PowerComponents {
     * Builder for PowerComponents.
     */
    static final class Builder {
        private static final byte POWER_MODEL_UNINITIALIZED = -1;

        private final BatteryConsumer.BatteryConsumerData mData;
        private final double mMinConsumedPowerThreshold;

        Builder(BatteryConsumer.BatteryConsumerData data, double minConsumedPowerThreshold) {
            mData = data;
            mMinConsumedPowerThreshold = minConsumedPowerThreshold;
            for (BatteryConsumer.Key key : mData.layout.keys) {
                if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                    mData.putInt(key.mPowerModelColumnIndex, POWER_MODEL_UNINITIALIZED);
                }
            }
        }

        /**
         * @deprecated use {@link #addConsumedPower(BatteryConsumer.Key, double, int)}
         * @deprecated use {@link #addConsumedPower(BatteryConsumer.Key, double)}
         */
        @Deprecated
        @NonNull
        public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower,
                int powerModel) {
        public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower) {
            mData.putDouble(key.mPowerColumnIndex, componentPower);
            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                mData.putInt(key.mPowerModelColumnIndex, powerModel);
            }
            return this;
        }

        @NonNull
        public Builder addConsumedPower(BatteryConsumer.Key key, double componentPower,
                int powerModel) {
        public Builder addConsumedPower(BatteryConsumer.Key key, double componentPower) {
            mData.putDouble(key.mPowerColumnIndex,
                    mData.getDouble(key.mPowerColumnIndex) + componentPower);
            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                mData.putInt(key.mPowerModelColumnIndex, powerModel);
            }
            return this;
        }

@@ -547,28 +514,6 @@ class PowerComponents {
                            mData.getLong(key.mDurationColumnIndex)
                                    + otherData.getLong(otherKey.mDurationColumnIndex));
                }
                if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
                    continue;
                }

                boolean undefined = false;
                if (otherKey.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
                    undefined = true;
                } else {
                    final int powerModel = mData.getInt(key.mPowerModelColumnIndex);
                    int otherPowerModel = otherData.getInt(otherKey.mPowerModelColumnIndex);
                    if (powerModel == POWER_MODEL_UNINITIALIZED) {
                        mData.putInt(key.mPowerModelColumnIndex, otherPowerModel);
                    } else if (powerModel != otherPowerModel
                            && otherPowerModel != POWER_MODEL_UNINITIALIZED) {
                        undefined = true;
                    }
                }

                if (undefined) {
                    mData.putInt(key.mPowerModelColumnIndex,
                            BatteryConsumer.POWER_MODEL_UNDEFINED);
                }
            }
        }

@@ -594,13 +539,6 @@ class PowerComponents {
        @NonNull
        public PowerComponents build() {
            for (BatteryConsumer.Key key : mData.layout.keys) {
                if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                    if (mData.getInt(key.mPowerModelColumnIndex) == POWER_MODEL_UNINITIALIZED) {
                        mData.putInt(key.mPowerModelColumnIndex,
                                BatteryConsumer.POWER_MODEL_UNDEFINED);
                    }
                }

                if (mMinConsumedPowerThreshold != 0) {
                    if (mData.getDouble(key.mPowerColumnIndex) < mMinConsumedPowerThreshold) {
                        mData.putDouble(key.mPowerColumnIndex, 0);
Loading