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

Commit 2148c1a2 authored by Lei Yu's avatar Lei Yu Committed by Android (Google) Code Review
Browse files

Merge "Fix issues in battery usage accounting" into qt-dev

parents ccbdd834 c89ba29e
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -352,15 +352,10 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro

    @VisibleForTesting
    boolean shouldHideSipper(BatterySipper sipper) {
        // Don't show hidden system module
        final String packageName = mBatteryUtils.getPackageName(sipper.getUid());
        if (!TextUtils.isEmpty(packageName)
                && AppUtils.isHiddenSystemModule(mContext, packageName)) {
            return true;
        }
        // Don't show over-counted and unaccounted in any condition
        // Don't show over-counted, unaccounted and hidden system module in any condition
        return sipper.drainType == BatterySipper.DrainType.OVERCOUNTED
                || sipper.drainType == BatterySipper.DrainType.UNACCOUNTED;
                || sipper.drainType == BatterySipper.DrainType.UNACCOUNTED
                || mBatteryUtils.isHiddenSystemModule(sipper);
    }

    @VisibleForTesting
+26 −3
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.fuelgauge.batterytip.StatsManagerConfig;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.fuelgauge.EstimateKt;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
@@ -189,8 +190,10 @@ public class BatteryUtils {
                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
                        && sipper.drainType != BatterySipper.DrainType.BLUETOOTH
                        && sipper.drainType != BatterySipper.DrainType.WIFI
                        && sipper.drainType != BatterySipper.DrainType.IDLE) {
                    // Don't add it if it is overcounted, unaccounted, wifi, bluetooth, or screen
                        && 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;
                }
            }
@@ -253,7 +256,27 @@ public class BatteryUtils {
                || drainType == BatterySipper.DrainType.WIFI
                || (sipper.totalPowerMah * SECONDS_IN_HOUR) < MIN_POWER_THRESHOLD_MILLI_AMP
                || mPowerUsageFeatureProvider.isTypeService(sipper)
                || mPowerUsageFeatureProvider.isTypeSystem(sipper);
                || mPowerUsageFeatureProvider.isTypeSystem(sipper)
                || isHiddenSystemModule(sipper);
    }

    /**
     * Return {@code true} if one of packages in {@code sipper} is hidden system modules
     */
    public boolean isHiddenSystemModule(BatterySipper sipper) {
        if (sipper.uidObj == null) {
            return false;
        }
        sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid());
        if (sipper.mPackages != null) {
            for (int i = 0, length = sipper.mPackages.length; i < length; i++) {
                if (AppUtils.isHiddenSystemModule(mContext, sipper.mPackages[i])) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
+26 −20
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;

import android.content.Context;
import android.os.BatteryStats;
import android.text.format.DateUtils;

import androidx.annotation.VisibleForTesting;

@@ -72,22 +71,33 @@ public class HighUsageDetector implements BatteryTipDetector {
        if (mPolicy.highUsageEnabled && mDischarging) {
            parseBatteryData();
            if (mDataParser.isDeviceHeavilyUsed() || mPolicy.testHighUsageTip) {
                final List<BatterySipper> batterySippers = mBatteryStatsHelper.getUsageList();
                for (int i = 0, size = batterySippers.size(); i < size; i++) {
                    final BatterySipper batterySipper = batterySippers.get(i);
                    if (!mBatteryUtils.shouldHideSipper(batterySipper)) {
                        final long foregroundTimeMs = mBatteryUtils.getProcessTimeMs(
                                BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
                                BatteryStats.STATS_SINCE_CHARGED);
                        if (foregroundTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
                final BatteryStats batteryStats = mBatteryStatsHelper.getStats();
                final List<BatterySipper> batterySippers
                        = new ArrayList<>(mBatteryStatsHelper.getUsageList());
                final double totalPower = mBatteryStatsHelper.getTotalPower();
                final int dischargeAmount = batteryStats != null
                        ? batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED)
                        : 0;

                Collections.sort(batterySippers,
                        (sipper1, sipper2) -> Double.compare(sipper2.totalSmearedPowerMah,
                                sipper1.totalSmearedPowerMah));
                for (BatterySipper batterySipper : batterySippers) {
                    final double percent = mBatteryUtils.calculateBatteryPercent(
                            batterySipper.totalSmearedPowerMah, totalPower, 0, 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;
                    }
                    mHighUsageAppList.add(new AppInfo.Builder()
                            .setUid(batterySipper.getUid())
                            .setPackageName(
                                    mBatteryUtils.getPackageName(batterySipper.getUid()))
                                    .setScreenOnTimeMs(foregroundTimeMs)
                            .build());
                    if (mHighUsageAppList.size() >= mPolicy.highUsageAppCount) {
                        break;
                    }
                    }

                }

                // When in test mode, add an app if necessary
@@ -97,10 +107,6 @@ public class HighUsageDetector implements BatteryTipDetector {
                            .setScreenOnTimeMs(TimeUnit.HOURS.toMillis(3))
                            .build());
                }

                Collections.sort(mHighUsageAppList, Collections.reverseOrder());
                mHighUsageAppList = mHighUsageAppList.subList(0,
                        Math.min(mPolicy.highUsageAppCount, mHighUsageAppList.size()));
            }
        }

+4 −9
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageManager;
import android.os.BatteryStats;
import android.os.UserManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
@@ -94,6 +96,7 @@ public class BatteryAppListPreferenceControllerTest {
        when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES);
        when(mNormalBatterySipper.getUid()).thenReturn(UID);
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        mNormalBatterySipper.uidObj = mock(BatteryStats.Uid.class);

        mPreferenceController = new BatteryAppListPreferenceController(mContext, KEY_APP_LIST, null,
                mSettingsActivity, mFragment);
@@ -203,15 +206,7 @@ public class BatteryAppListPreferenceControllerTest {

    @Test
    public void testShouldHideSipper_hiddenSystemModule_returnTrue() {
        ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", null);
        final String packageName = "test.hidden.module";
        final ModuleInfo moduleInfo = new ModuleInfo();
        moduleInfo.setPackageName(packageName);
        moduleInfo.setHidden(true);
        final List<ModuleInfo> modules = new ArrayList<>();
        modules.add(moduleInfo);
        when(mBatteryUtils.getPackageName(anyInt() /* uid */)).thenReturn(packageName);
        when(mPackageManager.getInstalledModules(anyInt() /* flags */)).thenReturn(modules);
        when(mBatteryUtils.isHiddenSystemModule(mNormalBatterySipper)).thenReturn(true);

        assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }
+9 −0
Original line number Diff line number Diff line
@@ -368,6 +368,15 @@ public class BatteryUtilsTest {
        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testShouldHideSipper_hiddenSystemModule_ReturnTrue() {
        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
        when(mNormalBatterySipper.getUid()).thenReturn(UID);
        when(mBatteryUtils.isHiddenSystemModule(mNormalBatterySipper)).thenReturn(true);

        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
    }

    @Test
    public void testCalculateBatteryPercent() {
        assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE,
Loading