Loading src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java +24 −12 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ public class BatteryDiffData { final Context context, final @NonNull List<BatteryDiffEntry> appDiffEntries, final @NonNull List<BatteryDiffEntry> systemDiffEntries, final Set<String> systemAppsSet, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids, final boolean isAccumulated) { mAppEntries = appDiffEntries; mSystemEntries = systemDiffEntries; Loading @@ -51,7 +52,8 @@ public class BatteryDiffData { final PowerUsageFeatureProvider featureProvider = FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context); purgeBatteryDiffData(featureProvider); combineBatteryDiffEntry(context, featureProvider, systemAppsSet); combineBatteryDiffEntry( context, featureProvider, systemAppsPackageNames, systemAppsUids); } processAndSortEntries(mAppEntries); Loading @@ -73,9 +75,13 @@ public class BatteryDiffData { } /** Combines into SystemAppsBatteryDiffEntry and OthersBatteryDiffEntry. */ private void combineBatteryDiffEntry(final Context context, final PowerUsageFeatureProvider featureProvider, final Set<String> systemAppsSet) { combineIntoSystemApps(context, featureProvider, systemAppsSet, mAppEntries); private void combineBatteryDiffEntry( final Context context, final PowerUsageFeatureProvider featureProvider, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids) { combineIntoSystemApps( context, featureProvider, systemAppsPackageNames, systemAppsUids, mAppEntries); combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries); } Loading Loading @@ -113,14 +119,16 @@ public class BatteryDiffData { private static void combineIntoSystemApps( final Context context, final PowerUsageFeatureProvider featureProvider, final Set<String> systemAppsSet, final List<BatteryDiffEntry> appEntries) { final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids, final @NonNull List<BatteryDiffEntry> appEntries) { final List<String> systemAppsAllowlist = featureProvider.getSystemAppsAllowlist(); BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null; final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator(); while (appListIterator.hasNext()) { final BatteryDiffEntry batteryDiffEntry = appListIterator.next(); if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, systemAppsSet)) { if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, systemAppsPackageNames, systemAppsUids)) { if (systemAppsDiffEntry == null) { systemAppsDiffEntry = new BatteryDiffEntry.SystemAppsBatteryDiffEntry(context); } Loading Loading @@ -168,8 +176,11 @@ public class BatteryDiffData { } @VisibleForTesting static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry, final List<String> systemAppsAllowlist, final Set<String> systemAppsSet) { static boolean needsCombineInSystemApp( final BatteryDiffEntry batteryDiffEntry, final @NonNull List<String> systemAppsAllowlist, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids) { if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) { return true; } Loading @@ -179,11 +190,12 @@ public class BatteryDiffData { return false; } if (systemAppsAllowlist != null && systemAppsAllowlist.contains(packageName)) { if (systemAppsAllowlist.contains(packageName)) { return true; } return systemAppsSet != null && systemAppsSet.contains(packageName); int uid = (int) batteryDiffEntry.mBatteryHistEntry.mUid; return systemAppsPackageNames.contains(packageName) || systemAppsUids.contains(uid); } /** Loading src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +58 −41 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; Loading @@ -84,7 +83,8 @@ public final class DataProcessor { private static final float TOTAL_HOURLY_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2; private static final long MIN_TIME_SLOT = DateUtils.HOUR_IN_MILLIS * 2; private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver"; private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new HashMap<>(); private static final String ANDROID_CORE_APPS_SHARED_USER_ID = "android.uid.shared"; private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new ArrayMap<>(); private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY = new BatteryHistEntry(new ContentValues()); Loading @@ -102,7 +102,7 @@ public final class DataProcessor { static long sTestCurrentTimeMillis = 0; @VisibleForTesting static Set<String> sTestSystemAppsSet; static Set<String> sTestSystemAppsPackageNames; @VisibleForTesting static IUsageStatsManager sUsageStatsManager = Loading Loading @@ -185,7 +185,7 @@ public final class DataProcessor { if (context == null) { return null; } final Map<Long, UsageEvents> resultMap = new HashMap(); final Map<Long, UsageEvents> resultMap = new ArrayMap(); final UserManager userManager = context.getSystemService(UserManager.class); if (userManager == null) { return null; Loading Loading @@ -276,12 +276,12 @@ public final class DataProcessor { // distribution. Collections.sort(appUsageEventList, TIMESTAMP_COMPARATOR); final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> resultMap = new HashMap<>(); new ArrayMap<>(); final long dailySize = hourlyBatteryLevelsPerDay.size(); for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) { final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyMap = new HashMap<>(); new ArrayMap<>(); resultMap.put(dailyIndex, dailyMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; Loading Loading @@ -391,7 +391,7 @@ public final class DataProcessor { if (appUsagePeriodMap == null) { return null; } final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new HashMap<>(); final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new ArrayMap<>(); insertHourlyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertDailyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertAllDeviceScreenOnTime(deviceScreenOnTime); Loading Loading @@ -433,7 +433,7 @@ public final class DataProcessor { final Context context) { final List<BatteryHistEntry> batteryHistEntryList = getBatteryHistListFromFromStatsService(context); return batteryHistEntryList == null ? new HashMap<>() return batteryHistEntryList == null ? new ArrayMap<>() : batteryHistEntryList.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e)); } Loading @@ -441,14 +441,14 @@ public final class DataProcessor { * @return Returns the processed history map which has interpolated to every hour data. * The start and end timestamp must be the even hours. * The keys of processed history map should contain every hour between the start and end * timestamp. If there's no data in some key, the value will be the empty hashmap. * timestamp. If there's no data in some key, the value will be the empty map. */ static Map<Long, Map<String, BatteryHistEntry>> getHistoryMapWithExpectedTimestamps( Context context, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) { final long startTime = System.currentTimeMillis(); final List<Long> rawTimestampList = new ArrayList<>(batteryHistoryMap.keySet()); final Map<Long, Map<String, BatteryHistEntry>> resultMap = new HashMap(); final Map<Long, Map<String, BatteryHistEntry>> resultMap = new ArrayMap(); if (rawTimestampList.isEmpty()) { Log.d(TAG, "empty batteryHistoryMap in getHistoryMapWithExpectedTimestamps()"); return resultMap; Loading Loading @@ -641,11 +641,12 @@ public final class DataProcessor { if (batteryHistoryMap.isEmpty()) { return null; } final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>(); final Set<String> systemAppsSet = getSystemAppsSet(context); final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>(); final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context); final Set<Integer> systemAppsUids = getSystemAppsUids(context); // Insert diff data from [0][0] to [maxDailyIndex][maxHourlyIndex]. insertHourlyUsageDiffData(context, systemAppsSet, hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap, resultMap); insertHourlyUsageDiffData(context, systemAppsPackageNames, systemAppsUids, hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap, resultMap); // Insert diff data from [0][SELECTED_INDEX_ALL] to [maxDailyIndex][SELECTED_INDEX_ALL]. insertDailyUsageDiffData(context, hourlyBatteryLevelsPerDay, resultMap); // Insert diff data [SELECTED_INDEX_ALL][SELECTED_INDEX_ALL]. Loading Loading @@ -704,9 +705,10 @@ public final class DataProcessor { return null; } final Set<String> systemAppsSet = getSystemAppsSet(context); return new BatteryDiffData( context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false); final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context); final Set<Integer> systemAppsUids = getSystemAppsUids(context); return new BatteryDiffData(context, appEntries, systemEntries, systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false); } /** Loading Loading @@ -743,7 +745,7 @@ public final class DataProcessor { return null; } final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new HashMap<>(); final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new ArrayMap<>(); for (int i = 0; i < usageEventsByInstanceId.size(); i++) { // The usage periods for an instance are determined by the usage events with its Loading Loading @@ -855,8 +857,8 @@ public final class DataProcessor { */ static Map<Integer, Map<Integer, BatteryDiffData>> getBatteryUsageMapFromStatsService( final Context context) { final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>(); final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>(); // Always construct the map whether the value is null or not. allUsageMap.put(SELECTED_INDEX_ALL, generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context))); Loading Loading @@ -937,7 +939,7 @@ public final class DataProcessor { final List<AppUsagePeriod> usagePeriodList, final long userId, final String packageName) { usagePeriodMap.computeIfAbsent(userId, key -> new HashMap<>()); usagePeriodMap.computeIfAbsent(userId, key -> new ArrayMap<>()); final Map<String, List<AppUsagePeriod>> packageNameMap = usagePeriodMap.get(userId); packageNameMap.computeIfAbsent(packageName, key -> new ArrayList<>()); packageNameMap.get(packageName).addAll(usagePeriodList); Loading Loading @@ -968,7 +970,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyAppUsageMap = appUsagePeriodMap.get(dailyIndex); final Map<Integer, Long> dailyScreenOnTime = new HashMap<>(); final Map<Integer, Long> dailyScreenOnTime = new ArrayMap<>(); resultMap.put(dailyIndex, dailyScreenOnTime); if (dailyAppUsageMap == null) { continue; Loading Loading @@ -1009,7 +1011,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { Map<Integer, Long> dailyResultMap = resultMap.get(dailyIndex); if (dailyResultMap == null) { dailyResultMap = new HashMap<>(); dailyResultMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyResultMap); } dailyResultMap.put( Loading @@ -1020,10 +1022,10 @@ public final class DataProcessor { private static void insertAllDeviceScreenOnTime( final Map<Integer, Map<Integer, Long>> resultMap) { final Map<Integer, Long> dailyAllMap = new HashMap<>(); final Map<Integer, Long> dailyAllMap = new ArrayMap<>(); resultMap.keySet().forEach( key -> dailyAllMap.put(key, resultMap.get(key).get(SELECTED_INDEX_ALL))); final Map<Integer, Long> allUsageMap = new HashMap<>(); final Map<Integer, Long> allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedScreenOnTime(dailyAllMap)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } Loading Loading @@ -1173,7 +1175,7 @@ public final class DataProcessor { // Case 1: upper timestamp is zero since scheduler is delayed! if (upperTimestamp == 0) { log(context, "job scheduler is delayed", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); return; } // Case 2: upper timestamp is closed to the current timestamp. Loading @@ -1186,7 +1188,7 @@ public final class DataProcessor { // Case 3: lower timestamp is zero before starting to collect data. if (lowerTimestamp == 0) { log(context, "no lower timestamp slot data", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); return; } interpolateHistoryForSlot(context, Loading Loading @@ -1222,12 +1224,12 @@ public final class DataProcessor { resultMap.put(currentSlot, upperEntryDataMap); } else { log(context, "in the different booting section", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); } return; } log(context, "apply interpolation arithmetic", currentSlot, null); final Map<String, BatteryHistEntry> newHistEntryMap = new HashMap<>(); final Map<String, BatteryHistEntry> newHistEntryMap = new ArrayMap<>(); final double timestampLength = upperTimestamp - lowerTimestamp; final double timestampDiff = currentSlot - lowerTimestamp; // Applies interpolation arithmetic for each BatteryHistEntry. Loading Loading @@ -1374,7 +1376,8 @@ public final class DataProcessor { private static void insertHourlyUsageDiffData( Context context, final Set<String> systemAppsSet, final Set<String> systemAppsPackageNames, final Set<Integer> systemAppsUids, final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap, final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> Loading @@ -1390,7 +1393,7 @@ public final class DataProcessor { // Math.abs(timestamp[i+1] data - timestamp[i] data); // since we want to aggregate every two hours data into a single time slot. for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) { final Map<Integer, BatteryDiffData> dailyDiffMap = new HashMap<>(); final Map<Integer, BatteryDiffData> dailyDiffMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyDiffMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; Loading @@ -1404,7 +1407,8 @@ public final class DataProcessor { workProfileUserId, hourlyIndex, timestamps, systemAppsSet, systemAppsPackageNames, systemAppsUids, appUsagePeriodMap == null || appUsagePeriodMap.get(dailyIndex) == null ? null Loading @@ -1422,7 +1426,7 @@ public final class DataProcessor { for (int index = 0; index < hourlyBatteryLevelsPerDay.size(); index++) { Map<Integer, BatteryDiffData> dailyUsageMap = resultMap.get(index); if (dailyUsageMap == null) { dailyUsageMap = new HashMap<>(); dailyUsageMap = new ArrayMap<>(); resultMap.put(index, dailyUsageMap); } dailyUsageMap.put( Loading @@ -1437,7 +1441,7 @@ public final class DataProcessor { final List<BatteryDiffData> diffDataList = new ArrayList<>(); resultMap.keySet().forEach( key -> diffDataList.add(resultMap.get(key).get(SELECTED_INDEX_ALL))); final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(context, diffDataList)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } Loading @@ -1449,7 +1453,8 @@ public final class DataProcessor { final int workProfileUserId, final int currentIndex, final List<Long> timestamps, final Set<String> systemAppsSet, final Set<String> systemAppsPackageNames, final Set<Integer> systemAppsUids, final Map<Long, Map<String, List<AppUsagePeriod>>> appUsageMap, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) { final List<BatteryDiffEntry> appEntries = new ArrayList<>(); Loading Loading @@ -1603,8 +1608,8 @@ public final class DataProcessor { return null; } return new BatteryDiffData( context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false); return new BatteryDiffData(context, appEntries, systemEntries, systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false); } private static long getScreenOnTime(@Nullable final List<AppUsagePeriod> appUsagePeriodList) { Loading Loading @@ -1662,7 +1667,7 @@ public final class DataProcessor { @Nullable private static BatteryDiffData getAccumulatedUsageDiffData( final Context context, final Collection<BatteryDiffData> diffEntryListData) { final Map<String, BatteryDiffEntry> diffEntryMap = new HashMap<>(); final Map<String, BatteryDiffEntry> diffEntryMap = new ArrayMap<>(); final List<BatteryDiffEntry> appEntries = new ArrayList<>(); final List<BatteryDiffEntry> systemEntries = new ArrayList<>(); Loading @@ -1688,7 +1693,8 @@ public final class DataProcessor { } return diffEntryList.isEmpty() ? null : new BatteryDiffData(context, appEntries, systemEntries, /* systemAppsSet= */ null, /* isAccumulated= */ true); systemEntries, /* systemAppsPackageNames= */ new ArraySet<>(), /* systemAppsUids= */ new ArraySet<>(), /* isAccumulated= */ true); } private static void computeUsageDiffDataPerEntry( Loading Loading @@ -1904,11 +1910,22 @@ public final class DataProcessor { return null; } private static Set<String> getSystemAppsSet(Context context) { return sTestSystemAppsSet != null ? sTestSystemAppsSet private static Set<String> getSystemAppsPackageNames(Context context) { return sTestSystemAppsPackageNames != null ? sTestSystemAppsPackageNames : AppListRepositoryUtil.getSystemPackageNames(context, context.getUserId(), false); } private static Set<Integer> getSystemAppsUids(Context context) { Set<Integer> result = new ArraySet<>(); try { result.add(context.getPackageManager().getUidForSharedUser( ANDROID_CORE_APPS_SHARED_USER_ID)); } catch (PackageManager.NameNotFoundException e) { // No Android Core Apps } return result; } private static long getCurrentTimeMillis() { return sTestCurrentTimeMillis > 0 ? sTestCurrentTimeMillis : System.currentTimeMillis(); } Loading tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public final class BatteryChartPreferenceControllerTest { Locale.setDefault(new Locale("en_US")); org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); DataProcessor.sTestSystemAppsSet = Set.of(); DataProcessor.sTestSystemAppsPackageNames = Set.of(); mFeatureFactory = FakeFeatureFactory.setupForTest(); mContext = spy(RuntimeEnvironment.application); doReturn(mContext).when(mContext).getApplicationContext(); Loading tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ public class BatteryDiffDataTest { createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ true); final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( hiddenDiffEntry, List.of(), Set.of()); hiddenDiffEntry, List.of(), Set.of(), Set.of()); assertThat(needsCombineInSystemApp).isTrue(); } Loading @@ -77,7 +77,7 @@ public class BatteryDiffDataTest { mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME)); batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME), Set.of()); assertThat(needsCombineInSystemApp).isTrue(); } Loading @@ -91,7 +91,7 @@ public class BatteryDiffDataTest { mApplicationInfo.flags = 0; final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( batteryDiffEntry, List.of(), Set.of()); batteryDiffEntry, List.of(), Set.of(), Set.of()); assertThat(needsCombineInSystemApp).isFalse(); } Loading tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -107,7 +107,7 @@ public final class BatteryUsageBreakdownControllerTest { mBatteryDiffEntry = spy(mBatteryDiffEntry); mBatteryUsageBreakdownController.mBatteryDiffData = new BatteryDiffData(mContext, Arrays.asList(mBatteryDiffEntry), Arrays.asList(), Set.of(), /* isAccumulated= */ false); Set.of(), Set.of(), /* isAccumulated= */ false); // Adds fake testing data. BatteryDiffEntry.sResourceCache.put( "fakeBatteryDiffEntryKey", Loading Loading
src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java +24 −12 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ public class BatteryDiffData { final Context context, final @NonNull List<BatteryDiffEntry> appDiffEntries, final @NonNull List<BatteryDiffEntry> systemDiffEntries, final Set<String> systemAppsSet, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids, final boolean isAccumulated) { mAppEntries = appDiffEntries; mSystemEntries = systemDiffEntries; Loading @@ -51,7 +52,8 @@ public class BatteryDiffData { final PowerUsageFeatureProvider featureProvider = FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context); purgeBatteryDiffData(featureProvider); combineBatteryDiffEntry(context, featureProvider, systemAppsSet); combineBatteryDiffEntry( context, featureProvider, systemAppsPackageNames, systemAppsUids); } processAndSortEntries(mAppEntries); Loading @@ -73,9 +75,13 @@ public class BatteryDiffData { } /** Combines into SystemAppsBatteryDiffEntry and OthersBatteryDiffEntry. */ private void combineBatteryDiffEntry(final Context context, final PowerUsageFeatureProvider featureProvider, final Set<String> systemAppsSet) { combineIntoSystemApps(context, featureProvider, systemAppsSet, mAppEntries); private void combineBatteryDiffEntry( final Context context, final PowerUsageFeatureProvider featureProvider, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids) { combineIntoSystemApps( context, featureProvider, systemAppsPackageNames, systemAppsUids, mAppEntries); combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries); } Loading Loading @@ -113,14 +119,16 @@ public class BatteryDiffData { private static void combineIntoSystemApps( final Context context, final PowerUsageFeatureProvider featureProvider, final Set<String> systemAppsSet, final List<BatteryDiffEntry> appEntries) { final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids, final @NonNull List<BatteryDiffEntry> appEntries) { final List<String> systemAppsAllowlist = featureProvider.getSystemAppsAllowlist(); BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null; final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator(); while (appListIterator.hasNext()) { final BatteryDiffEntry batteryDiffEntry = appListIterator.next(); if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, systemAppsSet)) { if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, systemAppsPackageNames, systemAppsUids)) { if (systemAppsDiffEntry == null) { systemAppsDiffEntry = new BatteryDiffEntry.SystemAppsBatteryDiffEntry(context); } Loading Loading @@ -168,8 +176,11 @@ public class BatteryDiffData { } @VisibleForTesting static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry, final List<String> systemAppsAllowlist, final Set<String> systemAppsSet) { static boolean needsCombineInSystemApp( final BatteryDiffEntry batteryDiffEntry, final @NonNull List<String> systemAppsAllowlist, final @NonNull Set<String> systemAppsPackageNames, final @NonNull Set<Integer> systemAppsUids) { if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) { return true; } Loading @@ -179,11 +190,12 @@ public class BatteryDiffData { return false; } if (systemAppsAllowlist != null && systemAppsAllowlist.contains(packageName)) { if (systemAppsAllowlist.contains(packageName)) { return true; } return systemAppsSet != null && systemAppsSet.contains(packageName); int uid = (int) batteryDiffEntry.mBatteryHistEntry.mUid; return systemAppsPackageNames.contains(packageName) || systemAppsUids.contains(uid); } /** Loading
src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +58 −41 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; Loading @@ -84,7 +83,8 @@ public final class DataProcessor { private static final float TOTAL_HOURLY_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2; private static final long MIN_TIME_SLOT = DateUtils.HOUR_IN_MILLIS * 2; private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver"; private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new HashMap<>(); private static final String ANDROID_CORE_APPS_SHARED_USER_ID = "android.uid.shared"; private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new ArrayMap<>(); private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY = new BatteryHistEntry(new ContentValues()); Loading @@ -102,7 +102,7 @@ public final class DataProcessor { static long sTestCurrentTimeMillis = 0; @VisibleForTesting static Set<String> sTestSystemAppsSet; static Set<String> sTestSystemAppsPackageNames; @VisibleForTesting static IUsageStatsManager sUsageStatsManager = Loading Loading @@ -185,7 +185,7 @@ public final class DataProcessor { if (context == null) { return null; } final Map<Long, UsageEvents> resultMap = new HashMap(); final Map<Long, UsageEvents> resultMap = new ArrayMap(); final UserManager userManager = context.getSystemService(UserManager.class); if (userManager == null) { return null; Loading Loading @@ -276,12 +276,12 @@ public final class DataProcessor { // distribution. Collections.sort(appUsageEventList, TIMESTAMP_COMPARATOR); final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> resultMap = new HashMap<>(); new ArrayMap<>(); final long dailySize = hourlyBatteryLevelsPerDay.size(); for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) { final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyMap = new HashMap<>(); new ArrayMap<>(); resultMap.put(dailyIndex, dailyMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; Loading Loading @@ -391,7 +391,7 @@ public final class DataProcessor { if (appUsagePeriodMap == null) { return null; } final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new HashMap<>(); final Map<Integer, Map<Integer, Long>> deviceScreenOnTime = new ArrayMap<>(); insertHourlyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertDailyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertAllDeviceScreenOnTime(deviceScreenOnTime); Loading Loading @@ -433,7 +433,7 @@ public final class DataProcessor { final Context context) { final List<BatteryHistEntry> batteryHistEntryList = getBatteryHistListFromFromStatsService(context); return batteryHistEntryList == null ? new HashMap<>() return batteryHistEntryList == null ? new ArrayMap<>() : batteryHistEntryList.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e)); } Loading @@ -441,14 +441,14 @@ public final class DataProcessor { * @return Returns the processed history map which has interpolated to every hour data. * The start and end timestamp must be the even hours. * The keys of processed history map should contain every hour between the start and end * timestamp. If there's no data in some key, the value will be the empty hashmap. * timestamp. If there's no data in some key, the value will be the empty map. */ static Map<Long, Map<String, BatteryHistEntry>> getHistoryMapWithExpectedTimestamps( Context context, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) { final long startTime = System.currentTimeMillis(); final List<Long> rawTimestampList = new ArrayList<>(batteryHistoryMap.keySet()); final Map<Long, Map<String, BatteryHistEntry>> resultMap = new HashMap(); final Map<Long, Map<String, BatteryHistEntry>> resultMap = new ArrayMap(); if (rawTimestampList.isEmpty()) { Log.d(TAG, "empty batteryHistoryMap in getHistoryMapWithExpectedTimestamps()"); return resultMap; Loading Loading @@ -641,11 +641,12 @@ public final class DataProcessor { if (batteryHistoryMap.isEmpty()) { return null; } final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>(); final Set<String> systemAppsSet = getSystemAppsSet(context); final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>(); final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context); final Set<Integer> systemAppsUids = getSystemAppsUids(context); // Insert diff data from [0][0] to [maxDailyIndex][maxHourlyIndex]. insertHourlyUsageDiffData(context, systemAppsSet, hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap, resultMap); insertHourlyUsageDiffData(context, systemAppsPackageNames, systemAppsUids, hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap, resultMap); // Insert diff data from [0][SELECTED_INDEX_ALL] to [maxDailyIndex][SELECTED_INDEX_ALL]. insertDailyUsageDiffData(context, hourlyBatteryLevelsPerDay, resultMap); // Insert diff data [SELECTED_INDEX_ALL][SELECTED_INDEX_ALL]. Loading Loading @@ -704,9 +705,10 @@ public final class DataProcessor { return null; } final Set<String> systemAppsSet = getSystemAppsSet(context); return new BatteryDiffData( context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false); final Set<String> systemAppsPackageNames = getSystemAppsPackageNames(context); final Set<Integer> systemAppsUids = getSystemAppsUids(context); return new BatteryDiffData(context, appEntries, systemEntries, systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false); } /** Loading Loading @@ -743,7 +745,7 @@ public final class DataProcessor { return null; } final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new HashMap<>(); final Map<Long, Map<String, List<AppUsagePeriod>>> allUsagePeriods = new ArrayMap<>(); for (int i = 0; i < usageEventsByInstanceId.size(); i++) { // The usage periods for an instance are determined by the usage events with its Loading Loading @@ -855,8 +857,8 @@ public final class DataProcessor { */ static Map<Integer, Map<Integer, BatteryDiffData>> getBatteryUsageMapFromStatsService( final Context context) { final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new HashMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>(); final Map<Integer, Map<Integer, BatteryDiffData>> resultMap = new ArrayMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>(); // Always construct the map whether the value is null or not. allUsageMap.put(SELECTED_INDEX_ALL, generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context))); Loading Loading @@ -937,7 +939,7 @@ public final class DataProcessor { final List<AppUsagePeriod> usagePeriodList, final long userId, final String packageName) { usagePeriodMap.computeIfAbsent(userId, key -> new HashMap<>()); usagePeriodMap.computeIfAbsent(userId, key -> new ArrayMap<>()); final Map<String, List<AppUsagePeriod>> packageNameMap = usagePeriodMap.get(userId); packageNameMap.computeIfAbsent(packageName, key -> new ArrayList<>()); packageNameMap.get(packageName).addAll(usagePeriodList); Loading Loading @@ -968,7 +970,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { final Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>> dailyAppUsageMap = appUsagePeriodMap.get(dailyIndex); final Map<Integer, Long> dailyScreenOnTime = new HashMap<>(); final Map<Integer, Long> dailyScreenOnTime = new ArrayMap<>(); resultMap.put(dailyIndex, dailyScreenOnTime); if (dailyAppUsageMap == null) { continue; Loading Loading @@ -1009,7 +1011,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { Map<Integer, Long> dailyResultMap = resultMap.get(dailyIndex); if (dailyResultMap == null) { dailyResultMap = new HashMap<>(); dailyResultMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyResultMap); } dailyResultMap.put( Loading @@ -1020,10 +1022,10 @@ public final class DataProcessor { private static void insertAllDeviceScreenOnTime( final Map<Integer, Map<Integer, Long>> resultMap) { final Map<Integer, Long> dailyAllMap = new HashMap<>(); final Map<Integer, Long> dailyAllMap = new ArrayMap<>(); resultMap.keySet().forEach( key -> dailyAllMap.put(key, resultMap.get(key).get(SELECTED_INDEX_ALL))); final Map<Integer, Long> allUsageMap = new HashMap<>(); final Map<Integer, Long> allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedScreenOnTime(dailyAllMap)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } Loading Loading @@ -1173,7 +1175,7 @@ public final class DataProcessor { // Case 1: upper timestamp is zero since scheduler is delayed! if (upperTimestamp == 0) { log(context, "job scheduler is delayed", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); return; } // Case 2: upper timestamp is closed to the current timestamp. Loading @@ -1186,7 +1188,7 @@ public final class DataProcessor { // Case 3: lower timestamp is zero before starting to collect data. if (lowerTimestamp == 0) { log(context, "no lower timestamp slot data", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); return; } interpolateHistoryForSlot(context, Loading Loading @@ -1222,12 +1224,12 @@ public final class DataProcessor { resultMap.put(currentSlot, upperEntryDataMap); } else { log(context, "in the different booting section", currentSlot, null); resultMap.put(currentSlot, new HashMap<>()); resultMap.put(currentSlot, new ArrayMap<>()); } return; } log(context, "apply interpolation arithmetic", currentSlot, null); final Map<String, BatteryHistEntry> newHistEntryMap = new HashMap<>(); final Map<String, BatteryHistEntry> newHistEntryMap = new ArrayMap<>(); final double timestampLength = upperTimestamp - lowerTimestamp; final double timestampDiff = currentSlot - lowerTimestamp; // Applies interpolation arithmetic for each BatteryHistEntry. Loading Loading @@ -1374,7 +1376,8 @@ public final class DataProcessor { private static void insertHourlyUsageDiffData( Context context, final Set<String> systemAppsSet, final Set<String> systemAppsPackageNames, final Set<Integer> systemAppsUids, final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap, final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> Loading @@ -1390,7 +1393,7 @@ public final class DataProcessor { // Math.abs(timestamp[i+1] data - timestamp[i] data); // since we want to aggregate every two hours data into a single time slot. for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) { final Map<Integer, BatteryDiffData> dailyDiffMap = new HashMap<>(); final Map<Integer, BatteryDiffData> dailyDiffMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyDiffMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; Loading @@ -1404,7 +1407,8 @@ public final class DataProcessor { workProfileUserId, hourlyIndex, timestamps, systemAppsSet, systemAppsPackageNames, systemAppsUids, appUsagePeriodMap == null || appUsagePeriodMap.get(dailyIndex) == null ? null Loading @@ -1422,7 +1426,7 @@ public final class DataProcessor { for (int index = 0; index < hourlyBatteryLevelsPerDay.size(); index++) { Map<Integer, BatteryDiffData> dailyUsageMap = resultMap.get(index); if (dailyUsageMap == null) { dailyUsageMap = new HashMap<>(); dailyUsageMap = new ArrayMap<>(); resultMap.put(index, dailyUsageMap); } dailyUsageMap.put( Loading @@ -1437,7 +1441,7 @@ public final class DataProcessor { final List<BatteryDiffData> diffDataList = new ArrayList<>(); resultMap.keySet().forEach( key -> diffDataList.add(resultMap.get(key).get(SELECTED_INDEX_ALL))); final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>(); final Map<Integer, BatteryDiffData> allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(context, diffDataList)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } Loading @@ -1449,7 +1453,8 @@ public final class DataProcessor { final int workProfileUserId, final int currentIndex, final List<Long> timestamps, final Set<String> systemAppsSet, final Set<String> systemAppsPackageNames, final Set<Integer> systemAppsUids, final Map<Long, Map<String, List<AppUsagePeriod>>> appUsageMap, final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) { final List<BatteryDiffEntry> appEntries = new ArrayList<>(); Loading Loading @@ -1603,8 +1608,8 @@ public final class DataProcessor { return null; } return new BatteryDiffData( context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false); return new BatteryDiffData(context, appEntries, systemEntries, systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false); } private static long getScreenOnTime(@Nullable final List<AppUsagePeriod> appUsagePeriodList) { Loading Loading @@ -1662,7 +1667,7 @@ public final class DataProcessor { @Nullable private static BatteryDiffData getAccumulatedUsageDiffData( final Context context, final Collection<BatteryDiffData> diffEntryListData) { final Map<String, BatteryDiffEntry> diffEntryMap = new HashMap<>(); final Map<String, BatteryDiffEntry> diffEntryMap = new ArrayMap<>(); final List<BatteryDiffEntry> appEntries = new ArrayList<>(); final List<BatteryDiffEntry> systemEntries = new ArrayList<>(); Loading @@ -1688,7 +1693,8 @@ public final class DataProcessor { } return diffEntryList.isEmpty() ? null : new BatteryDiffData(context, appEntries, systemEntries, /* systemAppsSet= */ null, /* isAccumulated= */ true); systemEntries, /* systemAppsPackageNames= */ new ArraySet<>(), /* systemAppsUids= */ new ArraySet<>(), /* isAccumulated= */ true); } private static void computeUsageDiffDataPerEntry( Loading Loading @@ -1904,11 +1910,22 @@ public final class DataProcessor { return null; } private static Set<String> getSystemAppsSet(Context context) { return sTestSystemAppsSet != null ? sTestSystemAppsSet private static Set<String> getSystemAppsPackageNames(Context context) { return sTestSystemAppsPackageNames != null ? sTestSystemAppsPackageNames : AppListRepositoryUtil.getSystemPackageNames(context, context.getUserId(), false); } private static Set<Integer> getSystemAppsUids(Context context) { Set<Integer> result = new ArraySet<>(); try { result.add(context.getPackageManager().getUidForSharedUser( ANDROID_CORE_APPS_SHARED_USER_ID)); } catch (PackageManager.NameNotFoundException e) { // No Android Core Apps } return result; } private static long getCurrentTimeMillis() { return sTestCurrentTimeMillis > 0 ? sTestCurrentTimeMillis : System.currentTimeMillis(); } Loading
tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public final class BatteryChartPreferenceControllerTest { Locale.setDefault(new Locale("en_US")); org.robolectric.shadows.ShadowSettings.set24HourTimeFormat(false); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); DataProcessor.sTestSystemAppsSet = Set.of(); DataProcessor.sTestSystemAppsPackageNames = Set.of(); mFeatureFactory = FakeFeatureFactory.setupForTest(); mContext = spy(RuntimeEnvironment.application); doReturn(mContext).when(mContext).getApplicationContext(); Loading
tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ public class BatteryDiffDataTest { createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ true); final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( hiddenDiffEntry, List.of(), Set.of()); hiddenDiffEntry, List.of(), Set.of(), Set.of()); assertThat(needsCombineInSystemApp).isTrue(); } Loading @@ -77,7 +77,7 @@ public class BatteryDiffDataTest { mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME)); batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME), Set.of()); assertThat(needsCombineInSystemApp).isTrue(); } Loading @@ -91,7 +91,7 @@ public class BatteryDiffDataTest { mApplicationInfo.flags = 0; final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp( batteryDiffEntry, List.of(), Set.of()); batteryDiffEntry, List.of(), Set.of(), Set.of()); assertThat(needsCombineInSystemApp).isFalse(); } Loading
tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -107,7 +107,7 @@ public final class BatteryUsageBreakdownControllerTest { mBatteryDiffEntry = spy(mBatteryDiffEntry); mBatteryUsageBreakdownController.mBatteryDiffData = new BatteryDiffData(mContext, Arrays.asList(mBatteryDiffEntry), Arrays.asList(), Set.of(), /* isAccumulated= */ false); Set.of(), Set.of(), /* isAccumulated= */ false); // Adds fake testing data. BatteryDiffEntry.sResourceCache.put( "fakeBatteryDiffEntryKey", Loading