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

Commit 66f97f4a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding some source hints when generating theme icons" into main

parents 2ed63f27 b2136311
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -242,7 +242,8 @@ public class BaseIconFactory implements AutoCloseable {
        if (adaptiveIcon instanceof Extender extender) {
            info = extender.getExtendedInfo(bitmap, color, this, scale[0]);
        } else if (IconProvider.ATLEAST_T && mThemeController != null && adaptiveIcon != null) {
            info.setThemedBitmap(mThemeController.createThemedBitmap(adaptiveIcon, info, this));
            info.setThemedBitmap(mThemeController.createThemedBitmap(
                    adaptiveIcon, info, this, options == null ? null : options.mSourceHint));
        }
        info = info.withFlags(getBitmapFlagOp(options));
        return info;
@@ -526,6 +527,8 @@ public class BaseIconFactory implements AutoCloseable {
        @Nullable
        Integer mExtractedColor;

        @Nullable
        SourceHint mSourceHint;

        /**
         * User for this icon, in case of badging
@@ -580,6 +583,15 @@ public class BaseIconFactory implements AutoCloseable {
            mGenerationMode = generationMode;
            return this;
        }

        /**
         * User for this icon, in case of badging
         */
        @NonNull
        public IconOptions setSourceHint(@Nullable SourceHint sourceHint) {
            mSourceHint = sourceHint;
            return this;
        }
    }

    /**
+15 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.launcher3.icons

import android.content.Context
import android.graphics.drawable.AdaptiveIconDrawable
import com.android.launcher3.icons.cache.CachingLogic
import com.android.launcher3.util.ComponentKey

/** Represents a themed version of a BitmapInfo */
interface ThemedBitmap {
@@ -34,9 +36,15 @@ interface IconThemeController {
        icon: AdaptiveIconDrawable,
        info: BitmapInfo,
        factory: BaseIconFactory,
        sourceHint: SourceHint? = null,
    ): ThemedBitmap?

    fun decode(data: ByteArray, info: BitmapInfo, factory: BaseIconFactory): ThemedBitmap?
    fun decode(
        data: ByteArray,
        info: BitmapInfo,
        factory: BaseIconFactory,
        sourceHint: SourceHint,
    ): ThemedBitmap?

    fun createThemedAdaptiveIcon(
        context: Context,
@@ -44,3 +52,9 @@ interface IconThemeController {
        info: BitmapInfo?,
    ): AdaptiveIconDrawable?
}

data class SourceHint(
    val key: ComponentKey,
    val logic: CachingLogic<*>,
    val freshnessId: String? = null,
)
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3.icons.cache

import android.content.ComponentName
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.UserHandle
import com.android.launcher3.icons.BaseIconFactory.IconOptions
import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.icons.IconProvider
import com.android.launcher3.icons.cache.BaseIconCache.Companion.EMPTY_CLASS_NAME

/** Caching logic for ApplicationInfo */
class AppInfoCachingLogic(
    private val pm: PackageManager,
    private val instantAppResolver: (ApplicationInfo) -> Boolean,
    private val errorLogger: (String, Exception?) -> Unit = { _, _ -> },
) : CachingLogic<ApplicationInfo> {

    override fun getComponent(info: ApplicationInfo) =
        ComponentName(info.packageName, info.packageName + EMPTY_CLASS_NAME)

    override fun getUser(info: ApplicationInfo) = UserHandle.getUserHandleForUid(info.uid)

    override fun getLabel(info: ApplicationInfo) = info.loadLabel(pm)

    override fun getApplicationInfo(info: ApplicationInfo) = info

    override fun loadIcon(
        context: Context,
        cache: BaseIconCache,
        info: ApplicationInfo,
    ): BitmapInfo {
        // 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
        val appIcon = cache.iconProvider.getIcon(info)
        if (context.packageManager.isDefaultApplicationIcon(appIcon)) {
            errorLogger.invoke(
                String.format("Default icon returned for %s", info.packageName),
                null,
            )
        }

        return cache.iconFactory.use { li ->
            li.createBadgedIconBitmap(
                appIcon,
                IconOptions()
                    .setUser(getUser(info))
                    .setInstantApp(instantAppResolver.invoke(info))
                    .setSourceHint(getSourceHint(info, cache)),
            )
        }
    }

    override fun getFreshnessIdentifier(item: ApplicationInfo, iconProvider: IconProvider) =
        iconProvider.getStateForApp(item)
}
+25 −25
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.launcher3.icons.BaseIconFactory.IconOptions
import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.icons.GraphicsUtils
import com.android.launcher3.icons.IconProvider
import com.android.launcher3.icons.SourceHint
import com.android.launcher3.icons.cache.CacheLookupFlag.Companion.DEFAULT_LOOKUP_FLAG
import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.FlagOp
@@ -95,6 +96,13 @@ constructor(
    private val userFlagOpMap = SparseArray<FlagOp>()
    private val userFormatString = SparseArray<String?>()

    private val appInfoCachingLogic =
        AppInfoCachingLogic(
            pm = context.packageManager,
            instantAppResolver = this::isInstantApp,
            errorLogger = this::logPersistently,
        )

    init {
        updateSystemState()
    }
@@ -273,8 +281,8 @@ constructor(
            if (addToMemCache) cache[cacheKey] = entry
            // Check the DB first.
            val cacheEntryUpdated =
                if (cursor == null) getEntryFromDBLocked(cacheKey, entry, lookupFlags)
                else updateTitleAndIconLocked(cacheKey, entry, cursor, lookupFlags)
                if (cursor == null) getEntryFromDBLocked(cacheKey, entry, lookupFlags, cachingLogic)
                else updateTitleAndIconLocked(cacheKey, entry, cursor, lookupFlags, cachingLogic)

            val obj: T? by lazy { infoProvider.get() }
            if (!cacheEntryUpdated) {
@@ -409,7 +417,7 @@ constructor(
            var entryUpdated = true

            // Check the DB first.
            if (!getEntryFromDBLocked(cacheKey, entry, lookupFlags)) {
            if (!getEntryFromDBLocked(cacheKey, entry, lookupFlags, appInfoCachingLogic)) {
                try {
                    val appInfo =
                        context
@@ -430,33 +438,18 @@ constructor(

                    // 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
                    val appIcon = iconProvider.getIcon(appInfo)
                    if (packageManager.isDefaultApplicationIcon(appIcon)) {
                        logPersistently(
                            String.format("Default icon returned for %s", appInfo.packageName),
                            null,
                        )
                    }

                    val iconInfo =
                        iconFactory.use { li ->
                            li.createBadgedIconBitmap(
                                appIcon,
                                IconOptions().setUser(user).setInstantApp(isInstantApp(appInfo)),
                            )
                        }

                    entry.title = appInfo.loadLabel(packageManager)
                    entry.contentDescription = getUserBadgedLabel(entry.title, user)
                    val iconInfo = appInfoCachingLogic.loadIcon(context, this, appInfo)
                    entry.bitmap =
                        if (lookupFlags.useLowRes())
                            BitmapInfo.of(BitmapInfo.LOW_RES_ICON, iconInfo.color)
                        else iconInfo

                    loadFallbackTitle(appInfo, entry, appInfoCachingLogic, user)

                    // Add the icon in the DB here, since these do not get written during
                    // package updates.
                    val freshnessId = iconProvider.getStateForApp(appInfo)
                    if (freshnessId != null) {
                    appInfoCachingLogic.getFreshnessIdentifier(appInfo, iconProvider)?.let {
                        freshnessId ->
                        addOrUpdateCacheDbEntry(
                            iconInfo,
                            entry.title,
@@ -483,6 +476,7 @@ constructor(
        cacheKey: ComponentKey,
        entry: CacheEntry,
        lookupFlags: CacheLookupFlag,
        cachingLogic: CachingLogic<*>,
    ): Boolean {
        var c: Cursor? = null
        Trace.beginSection("loadIconIndividually")
@@ -497,7 +491,7 @@ constructor(
                    ),
                )
            if (c.moveToNext()) {
                return updateTitleAndIconLocked(cacheKey, entry, c, lookupFlags)
                return updateTitleAndIconLocked(cacheKey, entry, c, lookupFlags, cachingLogic)
            }
        } catch (e: SQLiteException) {
            Log.d(TAG, "Error reading icon cache", e)
@@ -513,6 +507,7 @@ constructor(
        entry: CacheEntry,
        c: Cursor,
        lookupFlags: CacheLookupFlag,
        logic: CachingLogic<*>,
    ): Boolean {
        // Set the alpha to be 255, so that we never have a wrong color
        entry.bitmap =
@@ -552,7 +547,12 @@ constructor(
                val monoIconData = c.getBlob(INDEX_MONO_ICON)
                if (themeController != null && monoIconData != null) {
                    entry.bitmap.themedBitmap =
                        themeController.decode(monoIconData, entry.bitmap, factory)
                        themeController.decode(
                            data = monoIconData,
                            info = entry.bitmap,
                            factory = factory,
                            sourceHint = SourceHint(cacheKey, logic),
                        )
                }
            }
        }
+4 −1
Original line number Diff line number Diff line
@@ -35,7 +35,10 @@ object CachedObjectCachingLogic : CachingLogic<CachedObject> {
    override fun loadIcon(context: Context, cache: BaseIconCache, info: CachedObject): BitmapInfo {
        val d = info.getFullResIcon(cache) ?: return BitmapInfo.LOW_RES_INFO
        cache.iconFactory.use { li ->
            return li.createBadgedIconBitmap(d, IconOptions().setUser(info.user))
            return li.createBadgedIconBitmap(
                d,
                IconOptions().setUser(info.user).setSourceHint(getSourceHint(info, cache)),
            )
        }
    }

Loading