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

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

Convert UserPowerCalculator to work with BatteryUsageStats

Test: atest FrameworksCoreTests:com.android.internal.os.UserPowerCalculatorTest

Bug: 158137862

Change-Id: Ibfd0138a2e455e2242750518d89c620901326d11
parent 94d2b53e
Loading
Loading
Loading
Loading
+41 −4
Original line number Diff line number Diff line
@@ -33,20 +33,33 @@ public final class BatteryUsageStats implements Parcelable {
    private final int mDischargePercentage;
    private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers;
    private final ArrayList<SystemBatteryConsumer> mSystemBatteryConsumers;
    private final ArrayList<UserBatteryConsumer> mUserBatteryConsumers;

    private BatteryUsageStats(@NonNull Builder builder) {
        mConsumedPower = builder.mConsumedPower;
        mDischargePercentage = builder.mDischargePercentage;

        int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size();
        mUidBatteryConsumers = new ArrayList<>(uidBatteryConsumerCount);
        for (int i = 0; i < uidBatteryConsumerCount; i++) {
            mUidBatteryConsumers.add(builder.mUidBatteryConsumerBuilders.valueAt(i).build());
            UidBatteryConsumer.Builder uidBatteryConsumerBuilder =
                    builder.mUidBatteryConsumerBuilders.valueAt(i);
            if (!uidBatteryConsumerBuilder.isExcludedFromBatteryUsageStats()) {
                mUidBatteryConsumers.add(uidBatteryConsumerBuilder.build());
            }
        }

        int systemBatteryConsumerCount = builder.mSystemBatteryConsumerBuilders.size();
        mSystemBatteryConsumers = new ArrayList<>(systemBatteryConsumerCount);
        for (int i = 0; i < systemBatteryConsumerCount; i++) {
            mSystemBatteryConsumers.add(builder.mSystemBatteryConsumerBuilders.valueAt(i).build());
        }

        int userBatteryConsumerCount = builder.mUserBatteryConsumerBuilders.size();
        mUserBatteryConsumers = new ArrayList<>(userBatteryConsumerCount);
        for (int i = 0; i < userBatteryConsumerCount; i++) {
            mUserBatteryConsumers.add(builder.mUserBatteryConsumerBuilders.valueAt(i).build());
        }
    }

    /**
@@ -75,6 +88,11 @@ public final class BatteryUsageStats implements Parcelable {
        return mSystemBatteryConsumers;
    }

    @NonNull
    public List<UserBatteryConsumer> getUserBatteryConsumers() {
        return mUserBatteryConsumers;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -85,6 +103,8 @@ public final class BatteryUsageStats implements Parcelable {
        source.readParcelableList(mUidBatteryConsumers, getClass().getClassLoader());
        mSystemBatteryConsumers = new ArrayList<>();
        source.readParcelableList(mSystemBatteryConsumers, getClass().getClassLoader());
        mUserBatteryConsumers = new ArrayList<>();
        source.readParcelableList(mUserBatteryConsumers, getClass().getClassLoader());
        mConsumedPower = source.readDouble();
        mDischargePercentage = source.readInt();
    }
@@ -93,6 +113,7 @@ public final class BatteryUsageStats implements Parcelable {
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeParcelableList(mUidBatteryConsumers, flags);
        dest.writeParcelableList(mSystemBatteryConsumers, flags);
        dest.writeParcelableList(mUserBatteryConsumers, flags);
        dest.writeDouble(mConsumedPower);
        dest.writeInt(mDischargePercentage);
    }
@@ -120,6 +141,8 @@ public final class BatteryUsageStats implements Parcelable {
                new SparseArray<>();
        private final SparseArray<SystemBatteryConsumer.Builder> mSystemBatteryConsumerBuilders =
                new SparseArray<>();
        private final SparseArray<UserBatteryConsumer.Builder> mUserBatteryConsumerBuilders =
                new SparseArray<>();

        public Builder(int customPowerComponentCount, int customTimeComponentCount) {
            mCustomPowerComponentCount = customPowerComponentCount;
@@ -137,7 +160,6 @@ public final class BatteryUsageStats implements Parcelable {
        /**
         * Sets the battery discharge amount since BatteryStats reset as percentage of the full
         * charge.
         *
         */
        @SuppressLint("PercentageInt") // See b/174188159
        @NonNull
@@ -173,8 +195,8 @@ public final class BatteryUsageStats implements Parcelable {
        }

        /**
         * Creates or returns a exiting UidBatteryConsumer, which represents battery attribution
         * data for an individual UID.
         * Creates or returns a exiting SystemBatteryConsumer, which represents battery attribution
         * data for a specific drain type.
         */
        @NonNull
        public SystemBatteryConsumer.Builder getOrCreateSystemBatteryConsumerBuilder(
@@ -188,6 +210,21 @@ public final class BatteryUsageStats implements Parcelable {
            return builder;
        }

        /**
         * Creates or returns a exiting UserBatteryConsumer, which represents battery attribution
         * data for an individual {@link UserHandle}.
         */
        @NonNull
        public UserBatteryConsumer.Builder getOrCreateUserBatteryConsumerBuilder(int userId) {
            UserBatteryConsumer.Builder builder = mUserBatteryConsumerBuilders.get(userId);
            if (builder == null) {
                builder = new UserBatteryConsumer.Builder(mCustomPowerComponentCount,
                        mCustomTimeComponentCount, userId);
                mUserBatteryConsumerBuilders.put(userId, builder);
            }
            return builder;
        }

        @NonNull
        public SparseArray<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() {
            return mUidBatteryConsumerBuilders;
+33 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.os;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.util.IntArray;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -53,9 +54,13 @@ public final class BatteryUsageStatsQuery implements Parcelable {
    public static final int FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL = 1;

    private final int mFlags;
    @NonNull
    private final int[] mUserIds;

    private BatteryUsageStatsQuery(@NonNull Builder builder) {
        mFlags = builder.mFlags;
        mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray()
                : new int[]{UserHandle.USER_ALL};
    }

    @BatteryUsageStatsFlags
@@ -63,13 +68,28 @@ public final class BatteryUsageStatsQuery implements Parcelable {
        return mFlags;
    }

    /**
     * Returns an array of users for which the attribution is requested.  It may
     * contain {@link UserHandle#USER_ALL} to indicate that the attribution
     * should be performed for all users. Battery consumed by users <b>not</b> included
     * in this array will be returned in the aggregated form as {@link UserBatteryConsumer}'s.
     */
    @NonNull
    public int[] getUserIds() {
        return mUserIds;
    }

    private BatteryUsageStatsQuery(Parcel in) {
        mFlags = in.readInt();
        mUserIds = new int[in.readInt()];
        in.readIntArray(mUserIds);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mFlags);
        dest.writeInt(mUserIds.length);
        dest.writeIntArray(mUserIds);
    }

    @Override
@@ -96,6 +116,7 @@ public final class BatteryUsageStatsQuery implements Parcelable {
     */
    public static final class Builder {
        private int mFlags;
        private IntArray mUserIds;

        /**
         * Builds a read-only BatteryUsageStatsQuery object.
@@ -104,6 +125,18 @@ public final class BatteryUsageStatsQuery implements Parcelable {
            return new BatteryUsageStatsQuery(this);
        }

        /**
         * Add a user whose battery stats should be included in the battery usage stats.
         * {@link UserHandle#USER_ALL} will be used by default if no users are added explicitly.
         */
        public Builder addUser(@NonNull UserHandle userHandle) {
            if (mUserIds == null) {
                mUserIds = new IntArray(1);
            }
            mUserIds.add(userHandle.getIdentifier());
            return this;
        }

        /**
         * Sets flags to modify the behavior of {@link BatteryStatsManager#getBatteryUsageStats}.
         */
+21 −13
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
        private final int mUid;
        private String mPackageWithHighestDrain;
        private boolean mSystemComponent;
        private boolean mExcludeFromBatteryUsageStats;

        public Builder(int customPowerComponentCount, int customTimeComponentCount,
                BatteryStats.Uid batteryStatsUid) {
@@ -112,14 +113,6 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
            return mUid;
        }

        /**
         * Creates a read-only object out of the Builder values.
         */
        @NonNull
        public UidBatteryConsumer build() {
            return new UidBatteryConsumer(this);
        }

        /**
         * Sets the name of the package owned by this UID that consumed the highest amount
         * of power since BatteryStats reset.
@@ -131,12 +124,27 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
        }

        /**
         * Marks the UidBatteryConsumer as part of the system. For example,
         * the UidBatteryConsumer with the UID {@link Process#BLUETOOTH_UID} is considered
         * as a system component.
         * Marks the UidBatteryConsumer for exclusion from the result set.
         */
        public void setSystemComponent(boolean systemComponent) {
            mSystemComponent = systemComponent;
        public Builder excludeFromBatteryUsageStats() {
            mExcludeFromBatteryUsageStats = true;
            return this;
        }

        /**
         * Returns true if this UidBatteryConsumer must be excluded from the
         * BatteryUsageStats.
         */
        public boolean isExcludedFromBatteryUsageStats() {
            return mExcludeFromBatteryUsageStats;
        }

        /**
         * Creates a read-only object out of the Builder values.
         */
        @NonNull
        public UidBatteryConsumer build() {
            return new UidBatteryConsumer(this);
        }
    }
}
+115 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import android.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;

/**
 * Contains power consumption data attributed to a {@link UserHandle}.
 *
 * {@hide}
 */
public class UserBatteryConsumer extends BatteryConsumer implements Parcelable {
    private final int mUserId;

    public int getUserId() {
        return mUserId;
    }

    private UserBatteryConsumer(@NonNull UserBatteryConsumer.Builder builder) {
        super(builder.mPowerComponentsBuilder.build());
        mUserId = builder.mUserId;
    }

    private UserBatteryConsumer(Parcel in) {
        super(new PowerComponents(in));
        mUserId = in.readInt();
    }

    /**
     * Writes the contents into a Parcel.
     */
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(mUserId);
    }

    public static final Creator<UserBatteryConsumer> CREATOR =
            new Creator<UserBatteryConsumer>() {
                @Override
                public UserBatteryConsumer createFromParcel(Parcel in) {
                    return new UserBatteryConsumer(in);
                }

                @Override
                public UserBatteryConsumer[] newArray(int size) {
                    return new UserBatteryConsumer[size];
                }
            };

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

    /**
     * Builder for UserBatteryConsumer.
     */
    public static final class Builder extends BaseBuilder<Builder> {
        private final int mUserId;
        private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;

        Builder(int customPowerComponentCount, int customTimeComponentCount, int userId) {
            super(customPowerComponentCount, customTimeComponentCount);
            mUserId = userId;
        }

        /**
         * Add a UidBatteryConsumer to this UserBatteryConsumer.
         * <p>
         * Calculated power and duration components of the added UID battery consumers
         * are aggregated at the time the UserBatteryConsumer is built by the {@link #build()}
         * method.
         * </p>
         */
        public void addUidBatteryConsumer(UidBatteryConsumer.Builder uidBatteryConsumerBuilder) {
            if (mUidBatteryConsumers == null) {
                mUidBatteryConsumers = new ArrayList<>();
            }
            mUidBatteryConsumers.add(uidBatteryConsumerBuilder);
        }

        /**
         * Creates a read-only object out of the Builder values.
         */
        @NonNull
        public UserBatteryConsumer build() {
            if (mUidBatteryConsumers != null) {
                for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
                    UidBatteryConsumer.Builder uidBatteryConsumer = mUidBatteryConsumers.get(i);
                    mPowerComponentsBuilder.addPowerAndDuration(
                            uidBatteryConsumer.mPowerComponentsBuilder);
                }
            }
            return new UserBatteryConsumer(this);
        }
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -43,8 +43,7 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
     */
    @Override
    public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
            SparseArray<UserHandle> asUsers) {
            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
        final long durationMs = calculateDuration(batteryStats, rawRealtimeUs,
                BatteryStats.STATS_SINCE_CHARGED);
        final double powerMah = mPowerEstimator.calculatePower(durationMs);
Loading