Add cache for PackageManager.getPackageUid to improvement performance

Context: `PackageManager.getPackageUid` is IPC which could be slow. Add a map in BatteryDiffEntry to cache the data. The cache lifecycle would be the same as other cache in BatteryDiffEntry.

Test: manual
Bug: 304439237
Fix: 304439237
Change-Id: I98d9c8cfee24dd43e9a4037b1b61c8353bf1bcea
This commit is contained in:
Jun Lan
2023-11-01 16:05:06 +08:00
parent 1742fa2ed0
commit 29b243bb3e
2 changed files with 30 additions and 4 deletions

View File

@@ -45,6 +45,9 @@ public class BatteryDiffEntry {
// Caches app label and icon to improve loading performance. // Caches app label and icon to improve loading performance.
static final Map<String, BatteryEntry.NameAndIcon> sResourceCache = new HashMap<>(); static final Map<String, BatteryEntry.NameAndIcon> sResourceCache = new HashMap<>();
// Caches package name and uid to improve loading performance.
static final Map<String, Integer> sPackageNameAndUidCache = new HashMap<>();
// Whether a specific item is valid to launch restriction page? // Whether a specific item is valid to launch restriction page?
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
static final Map<String, Boolean> sValidForRestriction = new HashMap<>(); static final Map<String, Boolean> sValidForRestriction = new HashMap<>();
@@ -289,10 +292,20 @@ public class BatteryDiffEntry {
return false; return false;
} }
final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName); final int uid = getPackageUid(packageName);
return uid == BatteryUtils.UID_REMOVED_APPS || uid == BatteryUtils.UID_NULL; return uid == BatteryUtils.UID_REMOVED_APPS || uid == BatteryUtils.UID_NULL;
} }
private int getPackageUid(String packageName) {
if (sPackageNameAndUidCache.containsKey(packageName)) {
return sPackageNameAndUidCache.get(packageName);
}
int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
sPackageNameAndUidCache.put(packageName, uid);
return uid;
}
void loadLabelAndIcon() { void loadLabelAndIcon() {
if (mIsLoaded) { if (mIsLoaded) {
return; return;
@@ -498,10 +511,11 @@ public class BatteryDiffEntry {
return builder.toString(); return builder.toString();
} }
/** Clears app icon and label cache data. */ /** Clears all cache data. */
public static void clearCache() { public static void clearCache() {
sResourceCache.clear(); sResourceCache.clear();
sValidForRestriction.clear(); sValidForRestriction.clear();
sPackageNameAndUidCache.clear();
} }
private Drawable getBadgeIconForUser(Drawable icon) { private Drawable getBadgeIconForUser(Drawable icon) {

View File

@@ -352,16 +352,18 @@ public final class BatteryDiffEntryTest {
} }
@Test @Test
public void testClearCache_clearDataForResourcesAndFlags() { public void testClearCache_clearDataForAllCaches() {
BatteryDiffEntry.sResourceCache.put( BatteryDiffEntry.sResourceCache.put(
"fake application key", "fake application key",
new BatteryEntry.NameAndIcon("app label", null, /* iconId= */ 0)); new BatteryEntry.NameAndIcon("app label", null, /* iconId= */ 0));
BatteryDiffEntry.sValidForRestriction.put("fake application key", Boolean.valueOf(false)); BatteryDiffEntry.sValidForRestriction.put("fake application key", Boolean.valueOf(false));
BatteryDiffEntry.sPackageNameAndUidCache.put(PACKAGE_NAME, UID);
BatteryDiffEntry.clearCache(); BatteryDiffEntry.clearCache();
assertThat(BatteryDiffEntry.sResourceCache).isEmpty(); assertThat(BatteryDiffEntry.sResourceCache).isEmpty();
assertThat(BatteryDiffEntry.sValidForRestriction).isEmpty(); assertThat(BatteryDiffEntry.sValidForRestriction).isEmpty();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache).isEmpty();
} }
@Test @Test
@@ -445,7 +447,11 @@ public final class BatteryDiffEntryTest {
final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values)); final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
assertThat(entry.isSystemEntry()).isFalse(); assertThat(entry.isSystemEntry()).isFalse();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.containsKey(PACKAGE_NAME)).isFalse();
assertThat(entry.isUninstalledEntry()).isFalse(); assertThat(entry.isUninstalledEntry()).isFalse();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.containsKey(PACKAGE_NAME)).isTrue();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.get(PACKAGE_NAME)).isEqualTo(UID);
} }
@Test @Test
@@ -457,7 +463,9 @@ public final class BatteryDiffEntryTest {
final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values)); final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
assertThat(entry.isSystemEntry()).isFalse(); assertThat(entry.isSystemEntry()).isFalse();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.containsKey(PACKAGE_NAME)).isFalse();
assertThat(entry.isUninstalledEntry()).isFalse(); assertThat(entry.isUninstalledEntry()).isFalse();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.containsKey(PACKAGE_NAME)).isFalse();
} }
@Test @Test
@@ -469,7 +477,11 @@ public final class BatteryDiffEntryTest {
final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values)); final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
assertThat(entry.isSystemEntry()).isFalse(); assertThat(entry.isSystemEntry()).isFalse();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.containsKey(UNINSTALLED_PACKAGE_NAME))
.isFalse();
assertThat(entry.isUninstalledEntry()).isTrue(); assertThat(entry.isUninstalledEntry()).isTrue();
assertThat(BatteryDiffEntry.sPackageNameAndUidCache.get(UNINSTALLED_PACKAGE_NAME))
.isEqualTo(BatteryUtils.UID_NULL);
} }
@Test @Test
@@ -590,7 +602,7 @@ public final class BatteryDiffEntryTest {
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values); final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon(); doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon();
doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0); doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0);
doReturn(new String[] {"com.a.b.c"}).when(mMockPackageManager).getPackagesForUid(1001); doReturn(new String[]{"com.a.b.c"}).when(mMockPackageManager).getPackagesForUid(1001);
return createBatteryDiffEntry(10, batteryHistEntry); return createBatteryDiffEntry(10, batteryHistEntry);
} }