From 702921c9ff2db0f19d33543130e721412293a878 Mon Sep 17 00:00:00 2001 From: Zaiyue Xue Date: Mon, 13 Mar 2023 17:44:14 +0800 Subject: [PATCH] Put Android Core Apps under System apps Bug: 269188405 Fix: 269188405 Test: manual Change-Id: Ie79cdb71c48661b6b1e90b8d0e7836269cf665e7 --- .../batteryusage/BatteryDiffData.java | 36 ++++--- .../fuelgauge/batteryusage/DataProcessor.java | 99 +++++++++++-------- .../BatteryChartPreferenceControllerTest.java | 2 +- .../batteryusage/BatteryDiffDataTest.java | 6 +- .../BatteryUsageBreakdownControllerTest.java | 2 +- .../batteryusage/DataProcessorTest.java | 2 +- 6 files changed, 88 insertions(+), 59 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java index c5dfb0d357d..37eddf358a9 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java @@ -42,7 +42,8 @@ public class BatteryDiffData { final Context context, final @NonNull List appDiffEntries, final @NonNull List systemDiffEntries, - final Set systemAppsSet, + final @NonNull Set systemAppsPackageNames, + final @NonNull Set systemAppsUids, final boolean isAccumulated) { mAppEntries = appDiffEntries; mSystemEntries = systemDiffEntries; @@ -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); @@ -73,9 +75,13 @@ public class BatteryDiffData { } /** Combines into SystemAppsBatteryDiffEntry and OthersBatteryDiffEntry. */ - private void combineBatteryDiffEntry(final Context context, - final PowerUsageFeatureProvider featureProvider, final Set systemAppsSet) { - combineIntoSystemApps(context, featureProvider, systemAppsSet, mAppEntries); + private void combineBatteryDiffEntry( + final Context context, + final PowerUsageFeatureProvider featureProvider, + final @NonNull Set systemAppsPackageNames, + final @NonNull Set systemAppsUids) { + combineIntoSystemApps( + context, featureProvider, systemAppsPackageNames, systemAppsUids, mAppEntries); combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries); } @@ -113,14 +119,16 @@ public class BatteryDiffData { private static void combineIntoSystemApps( final Context context, final PowerUsageFeatureProvider featureProvider, - final Set systemAppsSet, - final List appEntries) { + final @NonNull Set systemAppsPackageNames, + final @NonNull Set systemAppsUids, + final @NonNull List appEntries) { final List systemAppsAllowlist = featureProvider.getSystemAppsAllowlist(); BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null; final Iterator 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); } @@ -168,8 +176,11 @@ public class BatteryDiffData { } @VisibleForTesting - static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry, - final List systemAppsAllowlist, final Set systemAppsSet) { + static boolean needsCombineInSystemApp( + final BatteryDiffEntry batteryDiffEntry, + final @NonNull List systemAppsAllowlist, + final @NonNull Set systemAppsPackageNames, + final @NonNull Set systemAppsUids) { if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) { return true; } @@ -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); } /** diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java index 2a926d02e91..fa43ec59568 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java @@ -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; @@ -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 EMPTY_BATTERY_MAP = new HashMap<>(); + private static final String ANDROID_CORE_APPS_SHARED_USER_ID = "android.uid.shared"; + private static final Map EMPTY_BATTERY_MAP = new ArrayMap<>(); private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY = new BatteryHistEntry(new ContentValues()); @@ -102,7 +102,7 @@ public final class DataProcessor { static long sTestCurrentTimeMillis = 0; @VisibleForTesting - static Set sTestSystemAppsSet; + static Set sTestSystemAppsPackageNames; @VisibleForTesting static IUsageStatsManager sUsageStatsManager = @@ -185,7 +185,7 @@ public final class DataProcessor { if (context == null) { return null; } - final Map resultMap = new HashMap(); + final Map resultMap = new ArrayMap(); final UserManager userManager = context.getSystemService(UserManager.class); if (userManager == null) { return null; @@ -275,12 +275,12 @@ public final class DataProcessor { // distribution. Collections.sort(appUsageEventList, TIMESTAMP_COMPARATOR); final Map>>>> resultMap = - new HashMap<>(); + new ArrayMap<>(); final long dailySize = hourlyBatteryLevelsPerDay.size(); for (int dailyIndex = 0; dailyIndex < hourlyBatteryLevelsPerDay.size(); dailyIndex++) { final Map>>> dailyMap = - new HashMap<>(); + new ArrayMap<>(); resultMap.put(dailyIndex, dailyMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; @@ -386,7 +386,7 @@ public final class DataProcessor { if (appUsagePeriodMap == null) { return null; } - final Map> deviceScreenOnTime = new HashMap<>(); + final Map> deviceScreenOnTime = new ArrayMap<>(); insertHourlyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertDailyDeviceScreenOnTime(appUsagePeriodMap, deviceScreenOnTime); insertAllDeviceScreenOnTime(deviceScreenOnTime); @@ -428,7 +428,7 @@ public final class DataProcessor { final Context context) { final List batteryHistEntryList = getBatteryHistListFromFromStatsService(context); - return batteryHistEntryList == null ? new HashMap<>() + return batteryHistEntryList == null ? new ArrayMap<>() : batteryHistEntryList.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e)); } @@ -436,14 +436,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> getHistoryMapWithExpectedTimestamps( Context context, final Map> batteryHistoryMap) { final long startTime = System.currentTimeMillis(); final List rawTimestampList = new ArrayList<>(batteryHistoryMap.keySet()); - final Map> resultMap = new HashMap(); + final Map> resultMap = new ArrayMap(); if (rawTimestampList.isEmpty()) { Log.d(TAG, "empty batteryHistoryMap in getHistoryMapWithExpectedTimestamps()"); return resultMap; @@ -636,11 +636,12 @@ public final class DataProcessor { if (batteryHistoryMap.isEmpty()) { return null; } - final Map> resultMap = new HashMap<>(); - final Set systemAppsSet = getSystemAppsSet(context); + final Map> resultMap = new ArrayMap<>(); + final Set systemAppsPackageNames = getSystemAppsPackageNames(context); + final Set 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]. @@ -699,9 +700,10 @@ public final class DataProcessor { return null; } - final Set systemAppsSet = getSystemAppsSet(context); - return new BatteryDiffData( - context, appEntries, systemEntries, systemAppsSet, /* isAccumulated= */ false); + final Set systemAppsPackageNames = getSystemAppsPackageNames(context); + final Set systemAppsUids = getSystemAppsUids(context); + return new BatteryDiffData(context, appEntries, systemEntries, + systemAppsPackageNames, systemAppsUids, /* isAccumulated= */ false); } /** @@ -738,7 +740,7 @@ public final class DataProcessor { return null; } - final Map>> allUsagePeriods = new HashMap<>(); + final Map>> 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 @@ -850,8 +852,8 @@ public final class DataProcessor { */ static Map> getBatteryUsageMapFromStatsService( final Context context) { - final Map> resultMap = new HashMap<>(); - final Map allUsageMap = new HashMap<>(); + final Map> resultMap = new ArrayMap<>(); + final Map allUsageMap = new ArrayMap<>(); // Always construct the map whether the value is null or not. allUsageMap.put(SELECTED_INDEX_ALL, generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context))); @@ -932,7 +934,7 @@ public final class DataProcessor { final List usagePeriodList, final long userId, final String packageName) { - usagePeriodMap.computeIfAbsent(userId, key -> new HashMap<>()); + usagePeriodMap.computeIfAbsent(userId, key -> new ArrayMap<>()); final Map> packageNameMap = usagePeriodMap.get(userId); packageNameMap.computeIfAbsent(packageName, key -> new ArrayList<>()); packageNameMap.get(packageName).addAll(usagePeriodList); @@ -963,7 +965,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { final Map>>> dailyAppUsageMap = appUsagePeriodMap.get(dailyIndex); - final Map dailyScreenOnTime = new HashMap<>(); + final Map dailyScreenOnTime = new ArrayMap<>(); resultMap.put(dailyIndex, dailyScreenOnTime); if (dailyAppUsageMap == null) { continue; @@ -1004,7 +1006,7 @@ public final class DataProcessor { for (final int dailyIndex : appUsagePeriodMap.keySet()) { Map dailyResultMap = resultMap.get(dailyIndex); if (dailyResultMap == null) { - dailyResultMap = new HashMap<>(); + dailyResultMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyResultMap); } dailyResultMap.put( @@ -1015,10 +1017,10 @@ public final class DataProcessor { private static void insertAllDeviceScreenOnTime( final Map> resultMap) { - final Map dailyAllMap = new HashMap<>(); + final Map dailyAllMap = new ArrayMap<>(); resultMap.keySet().forEach( key -> dailyAllMap.put(key, resultMap.get(key).get(SELECTED_INDEX_ALL))); - final Map allUsageMap = new HashMap<>(); + final Map allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedScreenOnTime(dailyAllMap)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } @@ -1168,7 +1170,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. @@ -1181,7 +1183,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, @@ -1217,12 +1219,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 newHistEntryMap = new HashMap<>(); + final Map newHistEntryMap = new ArrayMap<>(); final double timestampLength = upperTimestamp - lowerTimestamp; final double timestampDiff = currentSlot - lowerTimestamp; // Applies interpolation arithmetic for each BatteryHistEntry. @@ -1369,7 +1371,8 @@ public final class DataProcessor { private static void insertHourlyUsageDiffData( Context context, - final Set systemAppsSet, + final Set systemAppsPackageNames, + final Set systemAppsUids, final List hourlyBatteryLevelsPerDay, final Map> batteryHistoryMap, final Map>>>> @@ -1385,7 +1388,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 dailyDiffMap = new HashMap<>(); + final Map dailyDiffMap = new ArrayMap<>(); resultMap.put(dailyIndex, dailyDiffMap); if (hourlyBatteryLevelsPerDay.get(dailyIndex) == null) { continue; @@ -1399,7 +1402,8 @@ public final class DataProcessor { workProfileUserId, hourlyIndex, timestamps, - systemAppsSet, + systemAppsPackageNames, + systemAppsUids, appUsagePeriodMap == null || appUsagePeriodMap.get(dailyIndex) == null ? null @@ -1417,7 +1421,7 @@ public final class DataProcessor { for (int index = 0; index < hourlyBatteryLevelsPerDay.size(); index++) { Map dailyUsageMap = resultMap.get(index); if (dailyUsageMap == null) { - dailyUsageMap = new HashMap<>(); + dailyUsageMap = new ArrayMap<>(); resultMap.put(index, dailyUsageMap); } dailyUsageMap.put( @@ -1432,7 +1436,7 @@ public final class DataProcessor { final List diffDataList = new ArrayList<>(); resultMap.keySet().forEach( key -> diffDataList.add(resultMap.get(key).get(SELECTED_INDEX_ALL))); - final Map allUsageMap = new HashMap<>(); + final Map allUsageMap = new ArrayMap<>(); allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(context, diffDataList)); resultMap.put(SELECTED_INDEX_ALL, allUsageMap); } @@ -1444,7 +1448,8 @@ public final class DataProcessor { final int workProfileUserId, final int currentIndex, final List timestamps, - final Set systemAppsSet, + final Set systemAppsPackageNames, + final Set systemAppsUids, final Map>> appUsageMap, final Map> batteryHistoryMap) { final List appEntries = new ArrayList<>(); @@ -1598,8 +1603,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 appUsagePeriodList) { @@ -1657,7 +1662,7 @@ public final class DataProcessor { @Nullable private static BatteryDiffData getAccumulatedUsageDiffData( final Context context, final Collection diffEntryListData) { - final Map diffEntryMap = new HashMap<>(); + final Map diffEntryMap = new ArrayMap<>(); final List appEntries = new ArrayList<>(); final List systemEntries = new ArrayList<>(); @@ -1683,7 +1688,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( @@ -1899,11 +1905,22 @@ public final class DataProcessor { return null; } - private static Set getSystemAppsSet(Context context) { - return sTestSystemAppsSet != null ? sTestSystemAppsSet + private static Set getSystemAppsPackageNames(Context context) { + return sTestSystemAppsPackageNames != null ? sTestSystemAppsPackageNames : AppListRepositoryUtil.getSystemPackageNames(context, context.getUserId(), false); } + private static Set getSystemAppsUids(Context context) { + Set 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(); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java index 58c69b1e332..f18228bd84e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java @@ -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(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java index 0985fe7d54b..27539a58a54 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java @@ -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(); } @@ -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(); } @@ -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(); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java index 395f655d739..37f05bc0d8a 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBreakdownControllerTest.java @@ -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", diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java index 1d3f72b8bfd..693b735823d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java @@ -93,7 +93,7 @@ public final class DataProcessorTest { mFeatureFactory = FakeFeatureFactory.setupForTest(); mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider; - DataProcessor.sTestSystemAppsSet = Set.of(); + DataProcessor.sTestSystemAppsPackageNames = Set.of(); DataProcessor.sUsageStatsManager = mUsageStatsManager; doReturn(mIntent).when(mContext).registerReceiver( isA(BroadcastReceiver.class), isA(IntentFilter.class));