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

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

Merge "Add BatteryUsageStats.add(BatteryUsageStats)"

parents e72d7204 63d9aecd
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -90,6 +90,14 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
            return this;
        }

        /**
         * Adds power and usage duration from the supplied AggregateBatteryConsumer.
         */
        public void add(AggregateBatteryConsumer aggregateBatteryConsumer) {
            mConsumedPowerMah += aggregateBatteryConsumer.mConsumedPowerMah;
            mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents);
        }

        /**
         * Creates a read-only object out of the Builder values.
         */
+80 −5
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

@@ -94,11 +95,7 @@ public final class BatteryUsageStats implements Parcelable {
    private BatteryUsageStats(@NonNull Builder builder) {
        mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
        mStatsEndTimestampMs = builder.mStatsEndTimestampMs;
        if (builder.mStatsDurationMs != -1) {
            mStatsDurationMs = builder.mStatsDurationMs;
        } else {
            mStatsDurationMs = mStatsEndTimestampMs - mStatsStartTimestampMs;
        }
        mStatsDurationMs = builder.getStatsDuration();
        mBatteryCapacityMah = builder.mBatteryCapacityMah;
        mDischargePercentage = builder.mDischargePercentage;
        mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
@@ -608,6 +605,14 @@ public final class BatteryUsageStats implements Parcelable {
            return this;
        }

        private long getStatsDuration() {
            if (mStatsDurationMs != -1) {
                return mStatsDurationMs;
            } else {
                return mStatsEndTimestampMs - mStatsStartTimestampMs;
            }
        }

        /**
         * Sets the battery discharge amount since BatteryStats reset as percentage of the full
         * charge.
@@ -687,6 +692,22 @@ public final class BatteryUsageStats implements Parcelable {
            return builder;
        }

        /**
         * Creates or returns a UidBatteryConsumer, which represents battery attribution
         * data for an individual UID. This version of the method is not suitable for use
         * with PowerCalculators.
         */
        @NonNull
        public UidBatteryConsumer.Builder getOrCreateUidBatteryConsumerBuilder(int uid) {
            UidBatteryConsumer.Builder builder = mUidBatteryConsumerBuilders.get(uid);
            if (builder == null) {
                builder = new UidBatteryConsumer.Builder(mCustomPowerComponentNames,
                        mIncludePowerModels, uid);
                mUidBatteryConsumerBuilders.put(uid, builder);
            }
            return builder;
        }

        /**
         * Creates or returns a UserBatteryConsumer, which represents battery attribution
         * data for an individual {@link UserHandle}.
@@ -706,5 +727,59 @@ public final class BatteryUsageStats implements Parcelable {
        public SparseArray<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() {
            return mUidBatteryConsumerBuilders;
        }

        /**
         * Adds battery usage stats from another snapshots. The two snapshots are assumed to be
         * non-overlapping, meaning that the power consumption estimates and session durations
         * can be simply summed across the two snapshots.  This remains true even if the timestamps
         * seem to indicate that the sessions are in fact overlapping: timestamps may be off as a
         * result of realtime clock adjustments by the user or the system.
         */
        @NonNull
        public Builder add(BatteryUsageStats stats) {
            if (!Arrays.equals(mCustomPowerComponentNames, stats.mCustomPowerComponentNames)) {
                throw new IllegalArgumentException(
                        "BatteryUsageStats have different custom power components");
            }

            if (mUserBatteryConsumerBuilders.size() != 0
                    || !stats.getUserBatteryConsumers().isEmpty()) {
                throw new UnsupportedOperationException(
                        "Combining UserBatteryConsumers is not supported");
            }

            mDischargedPowerLowerBoundMah += stats.mDischargedPowerLowerBound;
            mDischargedPowerUpperBoundMah += stats.mDischargedPowerUpperBound;
            mDischargePercentage += stats.mDischargePercentage;

            mStatsDurationMs = getStatsDuration() + stats.getStatsDuration();

            if (mStatsStartTimestampMs == 0
                    || stats.mStatsStartTimestampMs < mStatsStartTimestampMs) {
                mStatsStartTimestampMs = stats.mStatsStartTimestampMs;
            }

            final boolean addingLaterSnapshot = stats.mStatsEndTimestampMs > mStatsEndTimestampMs;
            if (addingLaterSnapshot) {
                mStatsEndTimestampMs = stats.mStatsEndTimestampMs;
            }

            for (int scope = 0; scope < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; scope++) {
                getAggregateBatteryConsumerBuilder(scope)
                        .add(stats.mAggregateBatteryConsumers[scope]);
            }

            for (UidBatteryConsumer consumer : stats.getUidBatteryConsumers()) {
                getOrCreateUidBatteryConsumerBuilder(consumer.getUid()).add(consumer);
            }

            if (addingLaterSnapshot) {
                mBatteryCapacityMah = stats.mBatteryCapacityMah;
                mBatteryTimeRemainingMs = stats.mBatteryTimeRemainingMs;
                mChargeTimeRemainingMs = stats.mChargeTimeRemainingMs;
            }

            return this;
        }
    }
}
+56 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.os.PowerCalculator;

import java.io.PrintWriter;
import java.util.Arrays;

/**
 * Contains details of battery attribution data broken down to individual power drain types
@@ -36,9 +37,12 @@ class PowerComponents {
            - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;

    private final double mConsumedPowerMah;
    @NonNull
    private final double[] mPowerComponentsMah;
    @NonNull
    private final long[] mUsageDurationsMs;
    private final int mCustomPowerComponentCount;
    @Nullable
    private final byte[] mPowerModels;
    // Not written to Parcel and must be explicitly restored during the parent object's unparceling
    private String[] mCustomPowerComponentNames;
@@ -49,7 +53,7 @@ class PowerComponents {
        mPowerComponentsMah = builder.mPowerComponentsMah;
        mUsageDurationsMs = builder.mUsageDurationsMs;
        mConsumedPowerMah = builder.getTotalPower();
        mPowerModels = builder.mPowerModels;
        mPowerModels = builder.getPowerModels();
    }

    PowerComponents(@NonNull Parcel source) {
@@ -146,9 +150,13 @@ class PowerComponents {
        }
    }

    public boolean hasPowerModels() {
        return mPowerModels != null;
    }

    @BatteryConsumer.PowerModel
    int getPowerModel(@BatteryConsumer.PowerComponent int component) {
        if (mPowerModels == null) {
        if (!hasPowerModels()) {
            throw new IllegalStateException(
                    "Power model IDs were not requested in the BatteryUsageStatsQuery");
        }
@@ -298,6 +306,8 @@ class PowerComponents {
     * Builder for PowerComponents.
     */
    static final class Builder {
        private static final byte POWER_MODEL_UNINITIALIZED = -1;

        private final double[] mPowerComponentsMah;
        private final String[] mCustomPowerComponentNames;
        private final long[] mUsageDurationsMs;
@@ -311,6 +321,7 @@ class PowerComponents {
            mUsageDurationsMs = new long[powerComponentCount];
            if (includePowerModels) {
                mPowerModels = new byte[BatteryConsumer.POWER_COMPONENT_COUNT];
                Arrays.fill(mPowerModels, POWER_MODEL_UNINITIALIZED);
            } else {
                mPowerModels = null;
            }
@@ -412,12 +423,39 @@ class PowerComponents {
            return this;
        }

        public void addPowerAndDuration(Builder other) {
        public void addPowerAndDuration(PowerComponents.Builder other) {
            addPowerAndDuration(other.mPowerComponentsMah, other.mUsageDurationsMs,
                    other.mPowerModels);
        }

        public void addPowerAndDuration(PowerComponents other) {
            addPowerAndDuration(other.mPowerComponentsMah, other.mUsageDurationsMs,
                    other.mPowerModels);
        }

        private void addPowerAndDuration(double[] powerComponentsMah,
                long[] usageDurationsMs, byte[] powerModels) {
            if (mPowerComponentsMah.length != powerComponentsMah.length) {
                throw new IllegalArgumentException(
                        "Number of power components does not match: " + powerComponentsMah.length
                                + ", expected: " + mPowerComponentsMah.length);
            }

            for (int i = mPowerComponentsMah.length - 1; i >= 0; i--) {
                mPowerComponentsMah[i] += other.mPowerComponentsMah[i];
                mPowerComponentsMah[i] += powerComponentsMah[i];
            }
            for (int i = mUsageDurationsMs.length - 1; i >= 0; i--) {
                mUsageDurationsMs[i] += other.mUsageDurationsMs[i];
                mUsageDurationsMs[i] += usageDurationsMs[i];
            }
            if (mPowerModels != null && powerModels != null) {
                for (int i = mPowerModels.length - 1; i >= 0; i--) {
                    if (mPowerModels[i] == POWER_MODEL_UNINITIALIZED) {
                        mPowerModels[i] = powerModels[i];
                    } else if (mPowerModels[i] != powerModels[i]
                            && powerModels[i] != POWER_MODEL_UNINITIALIZED) {
                        mPowerModels[i] = BatteryConsumer.POWER_MODEL_UNDEFINED;
                    }
                }
            }
        }

@@ -433,6 +471,19 @@ class PowerComponents {
            return totalPowerMah;
        }

        private byte[] getPowerModels() {
            if (mPowerModels == null) {
                return null;
            }

            byte[] powerModels = new byte[mPowerModels.length];
            for (int i = mPowerModels.length - 1; i >= 0; i--) {
                powerModels[i] = mPowerModels[i] != POWER_MODEL_UNINITIALIZED ? mPowerModels[i]
                        : BatteryConsumer.POWER_MODEL_UNDEFINED;
            }
            return powerModels;
        }

        /**
         * Creates a read-only object out of the Builder values.
         */
+42 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.TextUtils;

import com.android.internal.os.PowerCalculator;

@@ -147,9 +148,10 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
     * Builder for UidBatteryConsumer.
     */
    public static final class Builder extends BaseBuilder<Builder> {
        private static final String PACKAGE_NAME_UNINITIALIZED = "";
        private final BatteryStats.Uid mBatteryStatsUid;
        private final int mUid;
        private String mPackageWithHighestDrain;
        private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED;
        public long mTimeInForegroundMs;
        public long mTimeInBackgroundMs;
        private boolean mExcludeFromBatteryUsageStats;
@@ -161,8 +163,19 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
            mUid = batteryStatsUid.getUid();
        }

        public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels,
                int uid) {
            super(customPowerComponentNames, includePowerModels);
            mBatteryStatsUid = null;
            mUid = uid;
        }

        @NonNull
        public BatteryStats.Uid getBatteryStatsUid() {
            if (mBatteryStatsUid == null) {
                throw new IllegalStateException(
                        "UidBatteryConsumer.Builder was initialized without a BatteryStats.Uid");
            }
            return mBatteryStatsUid;
        }

@@ -176,7 +189,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
         */
        @NonNull
        public Builder setPackageWithHighestDrain(@Nullable String packageName) {
            mPackageWithHighestDrain = packageName;
            mPackageWithHighestDrain = TextUtils.nullIfEmpty(packageName);
            return this;
        }

@@ -207,6 +220,30 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
            return this;
        }

        /**
         * Adds power and usage duration from the supplied UidBatteryConsumer.
         */
        public Builder add(UidBatteryConsumer consumer) {
            mPowerComponentsBuilder.addPowerAndDuration(consumer.mPowerComponents);
            mTimeInBackgroundMs += consumer.mTimeInBackgroundMs;
            mTimeInForegroundMs += consumer.mTimeInForegroundMs;

            if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
                mPackageWithHighestDrain = consumer.mPackageWithHighestDrain;
            } else if (!TextUtils.equals(mPackageWithHighestDrain,
                    consumer.mPackageWithHighestDrain)) {
                // Consider combining two UidBatteryConsumers with this distribution
                // of power drain between packages:
                // (package1=100, package2=10) and (package1=100, package2=101).
                // Since we don't know the actual power distribution between packages at this
                // point, we have no way to correctly declare package1 as the winner.
                // The naive logic of picking the consumer with the higher total consumed
                // power would produce an incorrect result.
                mPackageWithHighestDrain = null;
            }
            return this;
        }

        /**
         * Returns true if this UidBatteryConsumer must be excluded from the
         * BatteryUsageStats.
@@ -220,6 +257,9 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
         */
        @NonNull
        public UidBatteryConsumer build() {
            if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) {
                mPackageWithHighestDrain = null;
            }
            return new UidBatteryConsumer(this);
        }
    }
+251 −117

File changed.

Preview size limit exceeded, changes collapsed.