Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e61d197 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Converting some caching logic booleans to lookup flags

Bug: 366237794
Test: atest IconCacheTest
Flag: EXEMPT refactor

Change-Id: I0b00db66d0d3c63d0b2b96b57a9c8d28e8af554f
parent e5a3a2f2
Loading
Loading
Loading
Loading
+37 −44
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ public abstract class BaseIconCache {
            LookupFlag.DEFAULT,
            LookupFlag.USE_LOW_RES,
            LookupFlag.USE_PACKAGE_ICON,
            LookupFlag.SKIP_ADD_TO_MEM_CACHE
    }, flag = true)
    /** Various options to control cache lookup */
    public @interface LookupFlag {
@@ -112,6 +113,11 @@ public abstract class BaseIconCache {
         * entry fails
         */
        int USE_PACKAGE_ICON = 1 << 1;
        /**
         * When specified, the entry will not be added to the memory cache if it was not already
         * added by a previous lookup
         */
        int SKIP_ADD_TO_MEM_CACHE = 1 << 2;
    }

    public static class CacheEntry {
@@ -136,8 +142,10 @@ public abstract class BaseIconCache {
    @NonNull
    private final Map<ComponentKey, CacheEntry> mCache;

    public final Object iconUpdateToken = new Object();

    @NonNull
    protected final Handler mWorkerHandler;
    public final Handler workerHandler;

    protected int mIconDpi;

@@ -164,8 +172,6 @@ public abstract class BaseIconCache {
    @NonNull
    private final Looper mBgLooper;

    private volatile boolean mIconUpdateInProgress = false;

    public BaseIconCache(@NonNull final Context context, @Nullable final String dbFileName,
            @NonNull final Looper bgLooper, final int iconDpi, final int iconPixelSize,
            final boolean inMemoryCache) {
@@ -181,7 +187,7 @@ public abstract class BaseIconCache {
        mIconProvider = iconProvider;
        mPackageManager = context.getPackageManager();
        mBgLooper = bgLooper;
        mWorkerHandler = new Handler(mBgLooper);
        workerHandler = new Handler(mBgLooper);

        if (inMemoryCache) {
            mCache = new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
@@ -223,7 +229,7 @@ public abstract class BaseIconCache {
    public abstract BaseIconFactory getIconFactory();

    public void updateIconParams(final int iconDpi, final int iconPixelSize) {
        mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
        workerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
    }

    private synchronized void updateIconParamsBg(final int iconDpi, final int iconPixelSize) {
@@ -252,14 +258,6 @@ public abstract class BaseIconCache {
        return mIconProvider.getIcon(info, mIconDpi);
    }

    public void setIconUpdateInProgress(boolean updating) {
        mIconUpdateInProgress = updating;
    }

    public boolean isIconUpdateInProgress() {
        return mIconUpdateInProgress;
    }

    /**
     * Remove any records for the supplied ComponentName.
     */
@@ -340,53 +338,41 @@ public abstract class BaseIconCache {
    }

    /**
     * Adds an entry into the DB and the in-memory cache.
     *
     * @param replaceExisting if true, it will recreate the bitmap even if it already exists in
     *                        the memory. This is useful then the previous bitmap was created using
     *                        old data.
     * Adds/updates an entry into the DB and the in-memory cache. The update is skipped if the
     * entry fails to load
     */
    @VisibleForTesting
    public synchronized <T> void addIconToDBAndMemCache(@NonNull final T object,
    protected synchronized <T> void addIconToDBAndMemCache(@NonNull final T object,
            @NonNull final CachingLogic<T> cachingLogic, @NonNull final PackageInfo info,
            final long userSerial, final boolean replaceExisting) {
            final long userSerial) {
        UserHandle user = cachingLogic.getUser(object);
        ComponentName componentName = cachingLogic.getComponent(object);

        final ComponentKey key = new ComponentKey(componentName, user);
        CacheEntry entry = null;
        if (!replaceExisting) {
            entry = mCache.get(key);
            // We can't reuse the entry if the high-res icon is not present.
            if (entry == null || entry.bitmap.isNullOrLowRes()) {
                entry = null;
            }
        }
        if (entry == null) {
            entry = new CacheEntry();
            entry.bitmap = cachingLogic.loadIcon(mContext, this, object);
        }

        BitmapInfo bitmapInfo = cachingLogic.loadIcon(mContext, this, object);

        // Icon can't be loaded from cachingLogic, which implies alternative icon was loaded
        // (e.g. fallback icon, default icon). So we drop here since there's no point in caching
        // an empty entry.
        if (entry.bitmap.isNullOrLowRes() || isDefaultIcon(entry.bitmap, user)) {
        if (bitmapInfo.isNullOrLowRes() || isDefaultIcon(bitmapInfo, user)) {
            return;
        }

        CharSequence entryTitle = cachingLogic.getLabel(object);
        if (TextUtils.isEmpty(entryTitle)) {
            if (entryTitle == null) {
                Log.wtf(TAG, "No label returned from caching logic instance: " + cachingLogic);
            }
            entryTitle = componentName.getPackageName();
        }
        entry.title = entryTitle;

        entry.contentDescription = getUserBadgedLabel(entry.title, user);
        if (cachingLogic.addToMemCache()) mCache.put(key, entry);
        // Only add an entry in memory, if there was already something previously
        if (mCache.get(key) != null) {
            CacheEntry entry = new CacheEntry();
            entry.bitmap = bitmapInfo;
            entry.title = entryTitle;
            entry.contentDescription = getUserBadgedLabel(entryTitle, user);
            mCache.put(key, entry);
        }

        ContentValues values = newContentValues(
                entry.bitmap, entry.title.toString(), componentName.getPackageName());
                bitmapInfo, entryTitle.toString(), componentName.getPackageName());
        addIconToDB(values, componentName, info, userSerial,
                cachingLogic.getLastUpdatedTime(object, info));
    }
@@ -462,8 +448,10 @@ public abstract class BaseIconCache {
        CacheEntry entry = mCache.get(cacheKey);
        final boolean useLowResIcon = (lookupFlags & LookupFlag.USE_LOW_RES) != 0;
        if (entry == null || (entry.bitmap.isLowRes() && !useLowResIcon)) {
            boolean addToMemCache = entry != null
                    || (lookupFlags & LookupFlag.SKIP_ADD_TO_MEM_CACHE) == 0;
            entry = new CacheEntry();
            if (cachingLogic.addToMemCache()) {
            if (addToMemCache) {
                mCache.put(cacheKey, entry);
            }

@@ -596,8 +584,13 @@ public abstract class BaseIconCache {
    @Nullable
    protected CacheEntry getInMemoryPackageEntryLocked(@NonNull final String packageName,
            @NonNull final UserHandle user) {
        return getInMemoryEntryLocked(getPackageKey(packageName, user));
    }

    @VisibleForTesting
    public CacheEntry getInMemoryEntryLocked(ComponentKey key) {
        assertWorkerThread();
        return mCache.get(getPackageKey(packageName, user));
        return mCache.get(key);
    }

    /**
+2 −10
Original line number Diff line number Diff line
@@ -23,13 +23,8 @@ import com.android.launcher3.icons.BaseIconFactory.IconOptions
import com.android.launcher3.icons.BitmapInfo

/** Caching logic for ComponentWithLabelAndIcon */
class CachedObjectCachingLogic<T : BaseIconCache>
@JvmOverloads
constructor(
    context: Context,
    private val loadIcons: Boolean = true,
    private val addToMemCache: Boolean = true,
) : CachingLogic<CachedObject<T>> {
class CachedObjectCachingLogic<T : BaseIconCache>(context: Context) :
    CachingLogic<CachedObject<T>> {

    private val pm = context.packageManager

@@ -44,14 +39,11 @@ constructor(
        cache: BaseIconCache,
        info: CachedObject<T>,
    ): BitmapInfo {
        if (!loadIcons) return BitmapInfo.LOW_RES_INFO
        val d = info.getFullResIcon(cache as T) ?: return BitmapInfo.LOW_RES_INFO
        cache.iconFactory.use { li ->
            return li.createBadgedIconBitmap(d, IconOptions().setUser(info.user))
        }
    }

    override fun addToMemCache() = addToMemCache

    override fun getApplicationInfo(info: CachedObject<T>) = info.applicationInfo
}
+0 −7
Original line number Diff line number Diff line
@@ -62,11 +62,4 @@ public interface CachingLogic<T> {
    default long getLastUpdatedTime(@Nullable final T object, @NonNull final PackageInfo info) {
        return info.lastUpdateTime;
    }

    /**
     * Returns true the object should be added to mem cache; otherwise returns false.
     */
    default boolean addToMemCache() {
        return true;
    }
}
+7 −17
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@ public class IconCacheUpdateHandler {
     */
    private static final boolean MODE_CLEAR_VALID_ITEMS = false;

    static final Object ICON_UPDATE_TOKEN = new Object();

    private final HashMap<String, PackageInfo> mPkgInfoMap;
    private final BaseIconCache mIconCache;

@@ -84,7 +82,7 @@ public class IconCacheUpdateHandler {
        mPkgInfoMap = new HashMap<>();

        // Remove all active icon update tasks.
        mIconCache.mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
        mIconCache.workerHandler.removeCallbacksAndMessages(cache.iconUpdateToken);

        createPackageInfoMap();
    }
@@ -178,7 +176,6 @@ public class IconCacheUpdateHandler {
        if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
            ArrayDeque<T> appsToAdd = new ArrayDeque<>();
            appsToAdd.addAll(componentMap.values());
            mIconCache.setIconUpdateInProgress(true);
            new SerializedIconUpdateTask(userSerial, user, appsToAdd, appsToUpdate, cachingLogic,
                    onUpdateCallback).scheduleNext();
        }
@@ -309,8 +306,7 @@ public class IconCacheUpdateHandler {
                String pkg = mCachingLogic.getComponent(app).getPackageName();
                PackageInfo info = mPkgInfoMap.get(pkg);

                mIconCache.addIconToDBAndMemCache(
                        app, mCachingLogic, info, mUserSerial, true /*replace existing*/);
                mIconCache.addIconToDBAndMemCache(app, mCachingLogic, info, mUserSerial);
                mUpdatedPackages.add(pkg);

                if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
@@ -327,23 +323,17 @@ public class IconCacheUpdateHandler {
                // We do not check the mPkgInfoMap when generating the mAppsToAdd. Although every
                // app should have package info, this is not guaranteed by the api
                if (info != null) {
                    mIconCache.addIconToDBAndMemCache(app, mCachingLogic, info,
                            mUserSerial, false /*replace existing*/);
                    mIconCache.addIconToDBAndMemCache(app, mCachingLogic, info, mUserSerial);
                }

                if (!mAppsToAdd.isEmpty()) {
                // Let it run one more time.
                scheduleNext();
                } else if (!mIconCache.mWorkerHandler.hasMessages(0, ICON_UPDATE_TOKEN)) {
                    // This checks if there is a second icon update process happening
                    // before notifying BaseIconCache that the updates are over
                    mIconCache.setIconUpdateInProgress(false);
                }
            }
        }

        public void scheduleNext() {
            mIconCache.mWorkerHandler.postAtTime(this, ICON_UPDATE_TOKEN,
                    SystemClock.uptimeMillis() + 1);
            mIconCache.workerHandler.postAtTime(this,
                    mIconCache.iconUpdateToken, SystemClock.uptimeMillis() + 1);
        }
    }