diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index a1f5df24b85..c62af8fc34c 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -45,6 +45,8 @@ import com.android.internal.os.BatteryStatsHelper; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; +import com.android.settings.fuelgauge.batterytip.AnomalyInfo; +import com.android.settings.fuelgauge.batterytip.StatsManagerConfig; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.fuelgauge.PowerWhitelistBackend; @@ -511,10 +513,25 @@ public class BatteryUtils { return false; } + public boolean isPreOApp(final String[] packageNames) { + if (ArrayUtils.isEmpty(packageNames)) { + return false; + } + + for (String packageName : packageNames) { + if (isPreOApp(packageName)) { + return true; + } + } + + return false; + } + /** * Return {@code true} if we should hide anomaly app represented by {@code uid} */ - public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid) { + public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid, + AnomalyInfo anomalyInfo) { final String[] packageNames = mPackageManager.getPackagesForUid(uid); if (ArrayUtils.isEmpty(packageNames)) { // Don't show it if app has been uninstalled @@ -522,7 +539,13 @@ public class BatteryUtils { } return isSystemUid(uid) || powerWhitelistBackend.isWhitelisted(packageNames) - || (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames)); + || (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames)) + || (isExcessiveBackgroundAnomaly(anomalyInfo) && !isPreOApp(packageNames)); + } + + private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) { + return anomalyInfo.anomalyType + == StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE; } private boolean isSystemUid(int uid) { diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java index b6bcd54a692..84ef8641bdd 100644 --- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java +++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java @@ -155,44 +155,36 @@ public class AnomalyDetectionJobService extends JobService { final String packageName = batteryUtils.getPackageName(uid); final long versionCode = batteryUtils.getAppLongVersionCode(packageName); - final boolean anomalyDetected; - if (isExcessiveBackgroundAnomaly(anomalyInfo)) { - anomalyDetected = batteryUtils.isPreOApp(packageName); + if (batteryUtils.shouldHideAnomaly(powerWhitelistBackend, uid, anomalyInfo)) { + metricsFeatureProvider.action(context, + MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED, + packageName, + Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, + anomalyInfo.anomalyType), + Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE, + versionCode)); } else { - anomalyDetected = true; + if (autoFeatureOn && anomalyInfo.autoRestriction) { + // Auto restrict this app + batteryUtils.setForceAppStandby(uid, packageName, + AppOpsManager.MODE_IGNORED); + databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType, + AnomalyDatabaseHelper.State.AUTO_HANDLED, + timeMs); + } else { + databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType, + AnomalyDatabaseHelper.State.NEW, + timeMs); + } + metricsFeatureProvider.action(context, + MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED, + packageName, + Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, + anomalyInfo.anomalyType), + Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE, + versionCode)); } - if (anomalyDetected) { - if (batteryUtils.shouldHideAnomaly(powerWhitelistBackend, uid)) { - metricsFeatureProvider.action(context, - MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED, - packageName, - Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, - anomalyInfo.anomalyType), - Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE, - versionCode)); - } else { - if (autoFeatureOn && anomalyInfo.autoRestriction) { - // Auto restrict this app - batteryUtils.setForceAppStandby(uid, packageName, - AppOpsManager.MODE_IGNORED); - databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType, - AnomalyDatabaseHelper.State.AUTO_HANDLED, - timeMs); - } else { - databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType, - AnomalyDatabaseHelper.State.NEW, - timeMs); - } - metricsFeatureProvider.action(context, - MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED, - packageName, - Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, - anomalyInfo.anomalyType), - Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE, - versionCode)); - } - } } catch (NullPointerException | IndexOutOfBoundsException e) { Log.e(TAG, "Parse stats dimensions value error.", e); } @@ -229,11 +221,6 @@ public class AnomalyDetectionJobService extends JobService { return UID_NULL; } - private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) { - return anomalyInfo.anomalyType - == StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE; - } - @VisibleForTesting JobWorkItem dequeueWork(JobParameters parameters) { synchronized (mLock) { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java index 4fd3a825530..ac0b25a9646 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java @@ -53,6 +53,8 @@ import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; +import com.android.settings.fuelgauge.batterytip.AnomalyInfo; +import com.android.settings.fuelgauge.batterytip.StatsManagerConfig; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.fuelgauge.PowerWhitelistBackend; @@ -106,6 +108,9 @@ public class BatteryUtilsTest { private static final String HIGH_SDK_PACKAGE = "com.android.package.high"; private static final String LOW_SDK_PACKAGE = "com.android.package.low"; + private static final String INFO_EXCESSIVE = "anomaly_type=4,auto_restriction=false"; + private static final String INFO_WAKELOCK = "anomaly_type=1,auto_restriction=false"; + @Mock private BatteryStats.Uid mUid; @Mock @@ -146,6 +151,7 @@ public class BatteryUtilsTest { private ApplicationInfo mLowApplicationInfo; @Mock private PowerWhitelistBackend mPowerWhitelistBackend; + private AnomalyInfo mAnomalyInfo; private BatteryUtils mBatteryUtils; private FakeFeatureFactory mFeatureFactory; private PowerUsageFeatureProvider mProvider; @@ -211,6 +217,7 @@ public class BatteryUtilsTest { mBatteryUtils.mPowerUsageFeatureProvider = mProvider; doReturn(0L).when(mBatteryUtils) .getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong()); + mAnomalyInfo = new AnomalyInfo(INFO_WAKELOCK); mUsageList = new ArrayList<>(); mUsageList.add(mNormalBatterySipper); @@ -532,15 +539,26 @@ public class BatteryUtilsTest { } @Test - public void testIsLegacyApp_SdkLowerThanO_ReturnTrue() { + public void testIsPreOApp_SdkLowerThanO_ReturnTrue() { assertThat(mBatteryUtils.isPreOApp(LOW_SDK_PACKAGE)).isTrue(); } @Test - public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() { + public void testIsPreOApp_SdkLargerOrEqualThanO_ReturnFalse() { assertThat(mBatteryUtils.isPreOApp(HIGH_SDK_PACKAGE)).isFalse(); } + @Test + public void testIsPreOApp_containPreOApp_ReturnTrue() { + assertThat( + mBatteryUtils.isPreOApp(new String[]{HIGH_SDK_PACKAGE, LOW_SDK_PACKAGE})).isTrue(); + } + + @Test + public void testIsPreOApp_emptyList_ReturnFalse() { + assertThat(mBatteryUtils.isPreOApp(new String[]{})).isFalse(); + } + @Test public void testSetForceAppStandby_forcePreOApp_forceTwoRestrictions() { mBatteryUtils.setForceAppStandby(UID, LOW_SDK_PACKAGE, AppOpsManager.MODE_IGNORED); @@ -591,7 +609,8 @@ public class BatteryUtilsTest { doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue(); + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isTrue(); } @Test @@ -600,7 +619,8 @@ public class BatteryUtilsTest { doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); mHighApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue(); + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isTrue(); } @Test @@ -608,7 +628,8 @@ public class BatteryUtilsTest { final int systemUid = Process.ROOT_UID; doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(systemUid); - assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, systemUid)).isTrue(); + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, systemUid, + mAnomalyInfo)).isTrue(); } @Test @@ -616,13 +637,33 @@ public class BatteryUtilsTest { doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); doReturn(true).when(mPowerWhitelistBackend).isWhitelisted(new String[]{HIGH_SDK_PACKAGE}); - assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isTrue(); + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isTrue(); } @Test public void testShouldHideAnomaly_normalApp_returnFalse() { doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); - assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID)).isFalse(); + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isFalse(); + } + + @Test + public void testShouldHideAnomaly_excessivePriorOApp_returnFalse() { + doReturn(new String[]{LOW_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); + mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE); + + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isFalse(); + } + + @Test + public void testShouldHideAnomaly_excessiveOApp_returnTrue() { + doReturn(new String[]{HIGH_SDK_PACKAGE}).when(mPackageManager).getPackagesForUid(UID); + mAnomalyInfo = new AnomalyInfo(INFO_EXCESSIVE); + + assertThat(mBatteryUtils.shouldHideAnomaly(mPowerWhitelistBackend, UID, + mAnomalyInfo)).isTrue(); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java index 8df1f216421..b55bf6b956c 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java @@ -165,7 +165,7 @@ public class AnomalyDetectionJobServiceTest { doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE); doReturn(Process.FIRST_APPLICATION_UID).when( mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any()); - doReturn(true).when(mBatteryUtils).shouldHideAnomaly(any(), anyInt()); + doReturn(true).when(mBatteryUtils).shouldHideAnomaly(any(), anyInt(), any()); mAnomalyDetectionJobService.saveAnomalyToDatabase(mContext, mUserManager, mBatteryDatabaseManager, mBatteryUtils, mPolicy,