Loading src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +3 −8 Original line number Diff line number Diff line Loading @@ -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 Loading src/com/android/settings/fuelgauge/BatteryUtils.java +26 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading Loading @@ -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; } /** Loading src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java +26 −20 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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())); } } Loading tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java +4 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); } Loading tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +3 −8 Original line number Diff line number Diff line Loading @@ -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 Loading
src/com/android/settings/fuelgauge/BatteryUtils.java +26 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading Loading @@ -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; } /** Loading
src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java +26 −20 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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())); } } Loading
tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java +4 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); } Loading
tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -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