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

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

Remove smearing of hidden BatterySipper power

Bug: 182598424
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.applications.appinfo.AppBatteryPreferenceControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.BatteryUtilsTest

Change-Id: I78b8d7c4faafa83de198005617e99a7f54bcd174
parent 60cc9e50
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;

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

public class AppBatteryPreferenceController extends BasePreferenceController
@@ -162,13 +161,9 @@ public class AppBatteryPreferenceController extends BasePreferenceController
    void updateBattery() {
        mPreference.setEnabled(true);
        if (isBatteryStatsAvailable()) {
            final int dischargePercentage = mBatteryUsageStats.getDischargePercentage();

            final List<BatterySipper> usageList = new ArrayList<>(mBatteryHelper.getUsageList());
            final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList);
            final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
                    mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(),
                    hiddenAmount, dischargePercentage);
                    mBatteryUsageStats.getDischargePercentage());
            mBatteryPercent = Utils.formatPercentage(percentOfMax);
            mPreference.setSummary(mContext.getString(R.string.battery_summary, mBatteryPercent));
        } else {
+4 −3
Original line number Diff line number Diff line
@@ -189,8 +189,9 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
        if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) {
            final List<BatterySipper> usageList = getCoalescedUsageList(
                    USE_FAKE_DATA ? getFakeStats() : statsHelper.getUsageList());
            double hiddenPowerMah = showAllApps ? 0 :
            if (!showAllApps) {
                mBatteryUtils.removeHiddenBatterySippers(usageList);
            }
            mBatteryUtils.sortUsageList(usageList);

            final int numSippers = usageList.size();
@@ -199,7 +200,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
                double totalPower = USE_FAKE_DATA ? 4000 : statsHelper.getTotalPower();

                final double percentOfTotal = mBatteryUtils.calculateBatteryPercent(
                        sipper.totalPowerMah, totalPower, hiddenPowerMah, dischargeAmount);
                        sipper.totalPowerMah, totalPower, dischargeAmount);

                if (((int) (percentOfTotal + .5)) < 1) {
                    continue;
+4 −64
Original line number Diff line number Diff line
@@ -33,9 +33,7 @@ import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseLongArray;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@@ -174,72 +172,16 @@ public class BatteryUtils {
    }

    /**
     * Remove the {@link BatterySipper} that we should hide and smear the screen usage based on
     * foreground activity time.
     * Remove the {@link BatterySipper} that we should hide.
     *
     * @param sippers sipper list that need to check and remove
     * @return the total power of the hidden items of {@link BatterySipper}
     * for proportional smearing
     */
    public double removeHiddenBatterySippers(List<BatterySipper> sippers) {
        double proportionalSmearPowerMah = 0;
        BatterySipper screenSipper = null;
    public void removeHiddenBatterySippers(List<BatterySipper> sippers) {
        for (int i = sippers.size() - 1; i >= 0; i--) {
            final BatterySipper sipper = sippers.get(i);
            if (shouldHideSipper(sipper)) {
                sippers.remove(i);
                if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
                        && sipper.drainType != BatterySipper.DrainType.SCREEN
                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
                        && sipper.drainType != BatterySipper.DrainType.BLUETOOTH
                        && sipper.drainType != BatterySipper.DrainType.WIFI
                        && sipper.drainType != BatterySipper.DrainType.IDLE
                        && !isHiddenSystemModule(sipper)) {
                    // Don't add it if it is overcounted, unaccounted, wifi, bluetooth, screen
                    // or hidden system modules
                    proportionalSmearPowerMah += sipper.totalPowerMah;
                }
            }

            if (sipper.drainType == BatterySipper.DrainType.SCREEN) {
                screenSipper = sipper;
            }
        }

        smearScreenBatterySipper(sippers, screenSipper);

        return proportionalSmearPowerMah;
    }

    /**
     * Smear the screen on power usage among {@code sippers}, based on ratio of foreground activity
     * time.
     */
    @VisibleForTesting
    void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
        long totalActivityTimeMs = 0;
        final SparseLongArray activityTimeArray = new SparseLongArray();
        for (int i = 0, size = sippers.size(); i < size; i++) {
            final BatteryStats.Uid uid = sippers.get(i).uidObj;
            if (uid != null) {
                final long timeMs = getProcessTimeMs(StatusType.SCREEN_USAGE, uid,
                        BatteryStats.STATS_SINCE_CHARGED);
                activityTimeArray.put(uid.getUid(), timeMs);
                totalActivityTimeMs += timeMs;
            }
        }

        if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
            if (screenSipper == null) {
                Log.e(TAG, "screen sipper is null even when app screen time is not zero");
                return;
            }

            final double screenPowerMah = screenSipper.totalPowerMah;
            for (int i = 0, size = sippers.size(); i < size; i++) {
                final BatterySipper sipper = sippers.get(i);
                sipper.totalPowerMah += screenPowerMah * activityTimeArray.get(sipper.getUid(), 0)
                        / totalActivityTimeMs;
            }
        }
    }
@@ -287,19 +229,17 @@ public class BatteryUtils {
     *
     * @param powerUsageMah   power used by the app
     * @param totalPowerMah   total power used in the system
     * @param hiddenPowerMah  power used by no-actionable app that we want to hide, i.e. Screen,
     *                        Android OS.
     * @param dischargeAmount The discharge amount calculated by {@link BatteryStats}
     * @return A percentage value scaled by {@paramref dischargeAmount}
     * @see BatteryStats#getDischargeAmount(int)
     */
    public double calculateBatteryPercent(double powerUsageMah, double totalPowerMah,
            double hiddenPowerMah, int dischargeAmount) {
            int dischargeAmount) {
        if (totalPowerMah == 0) {
            return 0;
        }

        return (powerUsageMah / (totalPowerMah - hiddenPowerMah)) * dischargeAmount;
        return (powerUsageMah / totalPowerMah) * dischargeAmount;
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ public class HighUsageDetector implements BatteryTipDetector {
                                sipper1.totalSmearedPowerMah));
                for (BatterySipper batterySipper : batterySippers) {
                    final double percent = mBatteryUtils.calculateBatteryPercent(
                            batterySipper.totalSmearedPowerMah, totalPower, 0, dischargeAmount);
                            batterySipper.totalSmearedPowerMah, totalPower, dischargeAmount);
                    if ((percent + 0.5f < 1f) || mBatteryUtils.shouldHideSipper(batterySipper)) {
                        // Don't show it if we should hide or usage percentage is lower than 1%
                        continue;
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ public class AppBatteryPreferenceControllerTest {
        mController.mBatteryUsageStats = mBatteryUsageStats;
        mController.mUidBatteryConsumer = mUidBatteryConsumer;
        doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
                anyDouble(), anyDouble(), anyInt());
                anyDouble(), anyInt());
        doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
        mController.displayPreference(mScreen);

Loading