diff options
Diffstat (limited to 'iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java')
-rw-r--r-- | iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java | 282 |
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)); |