summaryrefslogtreecommitdiff
path: root/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
diff options
context:
space:
mode:
Diffstat (limited to 'iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java')
-rw-r--r--iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java282
1 files changed, 68 insertions, 214 deletions
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index 057bdc2..d685737 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -15,15 +15,10 @@
*/
package com.android.launcher3.icons.cache;
-import static android.graphics.BitmapFactory.decodeByteArray;
-
import static com.android.launcher3.icons.BaseIconFactory.getFullResDefaultActivityIcon;
import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON;
-import static com.android.launcher3.icons.GraphicsUtils.flattenBitmap;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static java.util.Objects.requireNonNull;
-
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
@@ -37,34 +32,26 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Process;
-import android.os.Trace;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
-import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.icons.BaseIconFactory;
-import com.android.launcher3.icons.BaseIconFactory.IconOptions;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.SQLiteCacheHelper;
-import java.nio.ByteBuffer;
import java.util.AbstractMap;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -90,6 +77,8 @@ public abstract class BaseIconCache {
public CharSequence contentDescription = "";
}
+ private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>();
+
protected final Context mContext;
protected final PackageManager mPackageManager;
@@ -101,9 +90,6 @@ public abstract class BaseIconCache {
protected LocaleList mLocaleList = LocaleList.getEmptyLocaleList();
protected String mSystemState = "";
- private BitmapInfo mDefaultIcon;
- private final SparseArray<FlagOp> mUserFlagOpMap = new SparseArray<>();
-
private final String mDbFileName;
private final Looper mBgLooper;
@@ -159,8 +145,7 @@ public abstract class BaseIconCache {
private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) {
mIconDpi = iconDpi;
- mDefaultIcon = null;
- mUserFlagOpMap.clear();
+ mDefaultIcons.clear();
mIconDb.clear();
mIconDb.close();
mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize);
@@ -191,6 +176,12 @@ public abstract class BaseIconCache {
return getFullResDefaultActivityIcon(mIconDpi);
}
+ private BitmapInfo makeDefaultIcon(UserHandle user) {
+ try (BaseIconFactory li = getIconFactory()) {
+ return li.makeDefaultIcon(user);
+ }
+ }
+
/**
* Remove any records for the supplied ComponentName.
*/
@@ -273,13 +264,7 @@ public abstract class BaseIconCache {
// (e.g. fallback icon, default icon). So we drop here since there's no point in caching
// an empty entry.
if (entry.bitmap.isNullOrLowRes()) return;
-
- CharSequence entryTitle = cachingLogic.getLabel(object);
- if (entryTitle == null) {
- Log.d(TAG, "No label returned from caching logic instance: " + cachingLogic);
- }
- entry.title = entryTitle;
-
+ entry.title = cachingLogic.getLabel(object);
entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
if (cachingLogic.addToMemCache()) mCache.put(key, entry);
@@ -303,26 +288,10 @@ public abstract class BaseIconCache {
}
public synchronized BitmapInfo getDefaultIcon(UserHandle user) {
- if (mDefaultIcon == null) {
- try (BaseIconFactory li = getIconFactory()) {
- mDefaultIcon = li.makeDefaultIcon();
- }
- }
- return mDefaultIcon.withFlags(getUserFlagOpLocked(user));
- }
-
- protected FlagOp getUserFlagOpLocked(UserHandle user) {
- int key = user.hashCode();
- int index;
- if ((index = mUserFlagOpMap.indexOfKey(key)) >= 0) {
- return mUserFlagOpMap.valueAt(index);
- } else {
- try (BaseIconFactory li = getIconFactory()) {
- FlagOp op = li.getBitmapFlagOp(new IconOptions().setUser(user));
- mUserFlagOpMap.put(key, op);
- return op;
- }
+ if (!mDefaultIcons.containsKey(user)) {
+ mDefaultIcons.put(user, makeDefaultIcon(user));
}
+ return mDefaultIcons.get(user);
}
public boolean isDefaultIcon(BitmapInfo icon, UserHandle user) {
@@ -337,20 +306,6 @@ public abstract class BaseIconCache {
@NonNull ComponentName componentName, @NonNull UserHandle user,
@NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
boolean usePackageIcon, boolean useLowResIcon) {
- return cacheLocked(
- componentName,
- user,
- infoProvider,
- cachingLogic,
- null,
- usePackageIcon,
- useLowResIcon);
- }
-
- protected <T> CacheEntry cacheLocked(
- @NonNull ComponentName componentName, @NonNull UserHandle user,
- @NonNull Supplier<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
- @Nullable Cursor cursor, boolean usePackageIcon, boolean useLowResIcon) {
assertWorkerThread();
ComponentKey cacheKey = new ComponentKey(componentName, user);
CacheEntry entry = mCache.get(cacheKey);
@@ -363,21 +318,31 @@ public abstract class BaseIconCache {
// Check the DB first.
T object = null;
boolean providerFetchedOnce = false;
- boolean cacheEntryUpdated = cursor == null
- ? getEntryFromDBLocked(cacheKey, entry, useLowResIcon)
- : updateTitleAndIconLocked(cacheKey, entry, cursor, useLowResIcon);
- if (!cacheEntryUpdated) {
+
+ if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) {
object = infoProvider.get();
providerFetchedOnce = true;
- loadFallbackIcon(
- object,
- entry,
- cachingLogic,
- usePackageIcon,
- /* usePackageTitle= */ true,
- componentName,
- user);
+ if (object != null) {
+ entry.bitmap = cachingLogic.loadIcon(mContext, object);
+ } else {
+ if (usePackageIcon) {
+ CacheEntry packageEntry = getEntryForPackageLocked(
+ componentName.getPackageName(), user, false);
+ if (packageEntry != null) {
+ if (DEBUG) Log.d(TAG, "using package default icon for " +
+ componentName.toShortString());
+ entry.bitmap = packageEntry.bitmap;
+ entry.title = packageEntry.title;
+ entry.contentDescription = packageEntry.contentDescription;
+ }
+ }
+ if (entry.bitmap == null) {
+ if (DEBUG) Log.d(TAG, "using default icon for " +
+ componentName.toShortString());
+ entry.bitmap = getDefaultIcon(user);
+ }
+ }
}
if (TextUtils.isEmpty(entry.title)) {
@@ -386,56 +351,15 @@ public abstract class BaseIconCache {
providerFetchedOnce = true;
}
if (object != null) {
- loadFallbackTitle(object, entry, cachingLogic, user);
+ entry.title = cachingLogic.getLabel(object);
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(
+ cachingLogic.getDescription(object, entry.title), user);
}
}
}
return entry;
}
- /**
- * Fallback method for loading an icon bitmap.
- */
- protected <T> void loadFallbackIcon(
- T object, CacheEntry entry, @NonNull CachingLogic<T> cachingLogic,
- boolean usePackageIcon, boolean usePackageTitle, @NonNull ComponentName componentName,
- @NonNull UserHandle user) {
- if (object != null) {
- entry.bitmap = cachingLogic.loadIcon(mContext, object);
- } else {
- if (usePackageIcon) {
- CacheEntry packageEntry = getEntryForPackageLocked(
- componentName.getPackageName(), user, false);
- if (packageEntry != null) {
- if (DEBUG) Log.d(TAG, "using package default icon for " +
- componentName.toShortString());
- entry.bitmap = packageEntry.bitmap;
- entry.contentDescription = packageEntry.contentDescription;
-
- if (usePackageTitle) {
- entry.title = packageEntry.title;
- }
- }
- }
- if (entry.bitmap == null) {
- if (DEBUG) Log.d(TAG, "using default icon for " +
- componentName.toShortString());
- entry.bitmap = getDefaultIcon(user);
- }
- }
- }
-
- /**
- * Fallback method for loading an app title.
- */
- protected <T> void loadFallbackTitle(
- T object, CacheEntry entry, @NonNull CachingLogic<T> cachingLogic,
- @NonNull UserHandle user) {
- entry.title = cachingLogic.getLabel(object);
- entry.contentDescription = mPackageManager.getUserBadgedLabel(
- cachingLogic.getDescription(object, entry.title), user);
- }
-
public synchronized void clear() {
assertWorkerThread();
mIconDb.clear();
@@ -461,7 +385,7 @@ public abstract class BaseIconCache {
}
if (icon != null) {
BaseIconFactory li = getIconFactory();
- entry.bitmap = li.createShapedIconBitmap(icon, new IconOptions().setUser(user));
+ entry.bitmap = li.createShapedIconBitmap(icon, user);
li.close();
}
if (!TextUtils.isEmpty(title) && entry.bitmap.icon != null) {
@@ -489,7 +413,7 @@ public abstract class BaseIconCache {
boolean entryUpdated = true;
// Check the DB first.
- if (!getEntryFromDBLocked(cacheKey, entry, useLowResIcon)) {
+ if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) {
try {
int flags = Process.myUserHandle().equals(user) ? 0 :
PackageManager.GET_UNINSTALLED_PACKAGES;
@@ -503,8 +427,8 @@ public abstract class BaseIconCache {
// Load the full res icon for the application, but if useLowResIcon is set, then
// only keep the low resolution icon instead of the larger full-sized icon
BitmapInfo iconInfo = li.createBadgedIconBitmap(
- appInfo.loadIcon(mPackageManager),
- new IconOptions().setUser(user).setInstantApp(isInstantApp(appInfo)));
+ appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion,
+ isInstantApp(appInfo));
li.close();
entry.title = appInfo.loadLabel(mPackageManager);
@@ -533,10 +457,8 @@ public abstract class BaseIconCache {
return entry;
}
- protected boolean getEntryFromDBLocked(
- ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
+ protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
Cursor c = null;
- Trace.beginSection("loadIconIndividually");
try {
c = mIconDb.query(
lowRes ? IconDB.COLUMNS_LOW_RES : IconDB.COLUMNS_HIGH_RES,
@@ -545,7 +467,26 @@ public abstract class BaseIconCache {
cacheKey.componentName.flattenToString(),
Long.toString(getSerialNumberForUser(cacheKey.user))});
if (c.moveToNext()) {
- return updateTitleAndIconLocked(cacheKey, entry, c, lowRes);
+ // Set the alpha to be 255, so that we never have a wrong color
+ entry.bitmap = BitmapInfo.of(LOW_RES_ICON, setColorAlphaBound(c.getInt(0), 255));
+ entry.title = c.getString(1);
+ if (entry.title == null) {
+ entry.title = "";
+ entry.contentDescription = "";
+ } else {
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(
+ entry.title, cacheKey.user);
+ }
+
+ if (!lowRes) {
+ try {
+ entry.bitmap = BitmapInfo.fromByteArray(
+ c.getBlob(2), entry.bitmap.color, cacheKey.user, this, mContext);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ return entry.bitmap != null;
}
} catch (SQLiteException e) {
Log.d(TAG, "Error reading icon cache", e);
@@ -553,62 +494,10 @@ public abstract class BaseIconCache {
if (c != null) {
c.close();
}
- Trace.endSection();
}
return false;
}
- private boolean updateTitleAndIconLocked(
- ComponentKey cacheKey, CacheEntry entry, Cursor c, boolean lowRes) {
- // Set the alpha to be 255, so that we never have a wrong color
- entry.bitmap = BitmapInfo.of(LOW_RES_ICON,
- setColorAlphaBound(c.getInt(IconDB.INDEX_COLOR), 255));
- entry.title = c.getString(IconDB.INDEX_TITLE);
- if (entry.title == null) {
- entry.title = "";
- entry.contentDescription = "";
- } else {
- entry.contentDescription = mPackageManager.getUserBadgedLabel(
- entry.title, cacheKey.user);
- }
-
- if (!lowRes) {
- byte[] data = c.getBlob(IconDB.INDEX_ICON);
- if (data == null) {
- return false;
- }
- try {
- BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
- decodeOptions.inPreferredConfig = Config.HARDWARE;
- entry.bitmap = BitmapInfo.of(
- requireNonNull(decodeByteArray(data, 0, data.length, decodeOptions)),
- entry.bitmap.color);
- } catch (Exception e) {
- return false;
- }
-
- // Decode mono bitmap
- data = c.getBlob(IconDB.INDEX_MONO_ICON);
- Bitmap icon = entry.bitmap.icon;
- if (data != null && data.length == icon.getHeight() * icon.getWidth()) {
- Bitmap monoBitmap = Bitmap.createBitmap(
- icon.getWidth(), icon.getHeight(), Config.ALPHA_8);
- monoBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data));
- Bitmap hwMonoBitmap = monoBitmap.copy(Config.HARDWARE, false /*isMutable*/);
- if (hwMonoBitmap != null) {
- monoBitmap.recycle();
- monoBitmap = hwMonoBitmap;
- }
- try (BaseIconFactory factory = getIconFactory()) {
- entry.bitmap.setMonoIcon(monoBitmap, factory);
- }
- }
- }
- entry.bitmap.flags = c.getInt(IconDB.INDEX_FLAGS);
- entry.bitmap = entry.bitmap.withFlags(getUserFlagOpLocked(cacheKey.user));
- return entry.bitmap != null;
- }
-
/**
* Returns a cursor for an arbitrary query to the cache db
*/
@@ -621,7 +510,7 @@ public abstract class BaseIconCache {
* Cache class to store the actual entries on disk
*/
public static final class IconDB extends SQLiteCacheHelper {
- private static final int RELEASE_VERSION = 34;
+ private static final int RELEASE_VERSION = 31;
public static final String TABLE_NAME = "icons";
public static final String COLUMN_ROWID = "rowid";
@@ -631,29 +520,14 @@ public abstract class BaseIconCache {
public static final String COLUMN_VERSION = "version";
public static final String COLUMN_ICON = "icon";
public static final String COLUMN_ICON_COLOR = "icon_color";
- public static final String COLUMN_MONO_ICON = "mono_icon";
- public static final String COLUMN_FLAGS = "flags";
public static final String COLUMN_LABEL = "label";
public static final String COLUMN_SYSTEM_STATE = "system_state";
public static final String COLUMN_KEYWORDS = "keywords";
+ public static final String[] COLUMNS_HIGH_RES = new String[] {
+ IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL, IconDB.COLUMN_ICON };
public static final String[] COLUMNS_LOW_RES = new String[] {
- COLUMN_COMPONENT,
- COLUMN_LABEL,
- COLUMN_ICON_COLOR,
- COLUMN_FLAGS};
- public static final String[] COLUMNS_HIGH_RES = Arrays.copyOf(COLUMNS_LOW_RES,
- COLUMNS_LOW_RES.length + 2, String[].class);
- static {
- COLUMNS_HIGH_RES[COLUMNS_LOW_RES.length] = COLUMN_ICON;
- COLUMNS_HIGH_RES[COLUMNS_LOW_RES.length + 1] = COLUMN_MONO_ICON;
- }
- private static final int INDEX_TITLE = Arrays.asList(COLUMNS_LOW_RES).indexOf(COLUMN_LABEL);
- private static final int INDEX_COLOR = Arrays.asList(COLUMNS_LOW_RES)
- .indexOf(COLUMN_ICON_COLOR);
- private static final int INDEX_FLAGS = Arrays.asList(COLUMNS_LOW_RES).indexOf(COLUMN_FLAGS);
- private static final int INDEX_ICON = COLUMNS_LOW_RES.length;
- private static final int INDEX_MONO_ICON = INDEX_ICON + 1;
+ IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
public IconDB(Context context, String dbFileName, int iconPixelSize) {
super(context, dbFileName, (RELEASE_VERSION << 16) + iconPixelSize, TABLE_NAME);
@@ -667,9 +541,7 @@ public abstract class BaseIconCache {
+ COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, "
+ COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, "
+ COLUMN_ICON + " BLOB, "
- + COLUMN_MONO_ICON + " BLOB, "
+ COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, "
- + COLUMN_FLAGS + " INTEGER NOT NULL DEFAULT 0, "
+ COLUMN_LABEL + " TEXT, "
+ COLUMN_SYSTEM_STATE + " TEXT, "
+ COLUMN_KEYWORDS + " TEXT, "
@@ -681,26 +553,8 @@ public abstract class BaseIconCache {
private ContentValues newContentValues(BitmapInfo bitmapInfo, String label,
String packageName, @Nullable String keywords) {
ContentValues values = new ContentValues();
- if (bitmapInfo.canPersist()) {
- values.put(IconDB.COLUMN_ICON, flattenBitmap(bitmapInfo.icon));
-
- // Persist mono bitmap as alpha channel
- Bitmap mono = bitmapInfo.getMono();
- if (mono != null && mono.getHeight() == bitmapInfo.icon.getHeight()
- && mono.getWidth() == bitmapInfo.icon.getWidth()
- && mono.getConfig() == Config.ALPHA_8) {
- byte[] pixels = new byte[mono.getWidth() * mono.getHeight()];
- mono.copyPixelsToBuffer(ByteBuffer.wrap(pixels));
- values.put(IconDB.COLUMN_MONO_ICON, pixels);
- } else {
- values.put(IconDB.COLUMN_MONO_ICON, (byte[]) null);
- }
- } else {
- values.put(IconDB.COLUMN_ICON, (byte[]) null);
- values.put(IconDB.COLUMN_MONO_ICON, (byte[]) null);
- }
+ values.put(IconDB.COLUMN_ICON, bitmapInfo.toByteArray());
values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color);
- values.put(IconDB.COLUMN_FLAGS, bitmapInfo.flags);
values.put(IconDB.COLUMN_LABEL, label);
values.put(IconDB.COLUMN_SYSTEM_STATE, getIconSystemState(packageName));