Add cache mechanism to improve icon and label loading performance

Bug: 185207505
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: I73dba5e40783f9ef4cfc0c4c33ea56b12754535d
This commit is contained in:
ykhung
2021-04-15 01:16:20 +08:00
committed by YUKAI HUNG
parent 3909ddb789
commit b2674eb5be
5 changed files with 153 additions and 22 deletions

View File

@@ -26,11 +26,18 @@ import androidx.annotation.VisibleForTesting;
import java.time.Duration;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/** A container class to carry battery data in a specific time slot. */
public final class BatteryDiffEntry {
private static final String TAG = "BatteryDiffEntry";
static Locale sCurrentLocale = null;
// Caches app label and icon to improve loading performance.
static final Map<String, BatteryEntry.NameAndIcon> sResourceCache = new HashMap<>();
/** A comparator for {@link BatteryDiffEntry} based on consumed percentage. */
public static final Comparator<BatteryDiffEntry> COMPARATOR =
(a, b) -> Double.compare(b.getPercentOfTotal(), a.getPercentOfTotal());
@@ -97,14 +104,7 @@ public final class BatteryDiffEntry {
/** Gets the app icon {@link Drawable} for this entry. */
public Drawable getAppIcon() {
loadLabelAndIcon();
if (mBatteryHistEntry.mConsumerType !=
ConvertUtils.CONSUMER_TYPE_UID_BATTERY) {
return mAppIcon;
}
// Returns default application icon if UID_BATTERY icon is null.
return mAppIcon == null
? mContext.getPackageManager().getDefaultActivityIcon()
: mAppIcon;
return mAppIcon;
}
/** Gets the searching package name for UID battery type. */
@@ -140,11 +140,37 @@ public final class BatteryDiffEntry {
}
break;
case ConvertUtils.CONSUMER_TYPE_UID_BATTERY:
final BatteryEntry.NameAndIcon nameAndIcon = getCache();
if (nameAndIcon != null) {
mAppLabel = nameAndIcon.name;
mAppIcon = nameAndIcon.icon;
break;
}
loadNameAndIconForUid();
// Uses application default icon if we cannot find it from package.
if (mAppIcon == null) {
mAppIcon = mContext.getPackageManager().getDefaultActivityIcon();
}
if (mAppLabel != null && mAppIcon != null) {
sResourceCache.put(
mBatteryHistEntry.getKey(),
new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /*iconId=*/ 0));
}
break;
}
}
private BatteryEntry.NameAndIcon getCache() {
final Locale locale = Locale.getDefault();
if (sCurrentLocale != locale) {
Log.d(TAG, String.format("clearCache() locale is changed from %s to %s",
sCurrentLocale, locale));
sCurrentLocale = locale;
clearCache();
}
return sResourceCache.get(mBatteryHistEntry.getKey());
}
private void loadNameAndIconForUid() {
final String packageName = mBatteryHistEntry.mPackageName;
final PackageManager packageManager = mContext.getPackageManager();
@@ -153,7 +179,9 @@ public final class BatteryDiffEntry {
try {
final ApplicationInfo appInfo =
packageManager.getApplicationInfo(packageName, /*no flags*/ 0);
mAppLabel = packageManager.getApplicationLabel(appInfo).toString();
if (appInfo != null) {
mAppLabel = packageManager.getApplicationLabel(appInfo).toString();
}
} catch (NameNotFoundException e) {
Log.e(TAG, "failed to retrieve ApplicationInfo for: " + packageName);
mAppLabel = packageName;
@@ -203,6 +231,10 @@ public final class BatteryDiffEntry {
return builder.toString();
}
static void clearCache() {
sResourceCache.clear();
}
private static <T> T getNonNull(T originalObj, T newObj) {
return newObj != null ? newObj : originalObj;
}