From 23252726b04df6f2c1894a5a32e336cff4e7f0b8 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:41:30 +0100 Subject: [PATCH] Don't store compat themed icons in database --- .../de/mm20/launcher2/database/IconDao.kt | 6 - .../de/mm20/launcher2/ktx/XmlPullParser.kt | 5 +- .../launcher2/icons/DynamicCalendarIcon.kt | 74 +++------ .../mm20/launcher2/icons/IconPackManager.kt | 46 ++---- .../de/mm20/launcher2/icons/IconRepository.kt | 12 +- .../java/de/mm20/launcher2/icons/Module.kt | 1 - .../icons/ThemedDynamicCalendarIcon.kt | 58 +++++++ .../compat/AdaptiveIconDrawableCompat.kt | 150 ++++++++++++++++++ .../icons/compat/ThemedIconCompat.kt | 26 --- .../loaders/CompatThemedIconInstaller.kt | 109 ------------- .../icons/providers/CalendarIconProvider.kt | 5 +- .../icons/providers/CompatIconProvider.kt | 39 +++++ .../providers/CompatThemedIconProvider.kt | 17 -- 13 files changed, 289 insertions(+), 259 deletions(-) create mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/ThemedDynamicCalendarIcon.kt create mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/compat/AdaptiveIconDrawableCompat.kt delete mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/compat/ThemedIconCompat.kt delete mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/loaders/CompatThemedIconInstaller.kt create mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatIconProvider.kt delete mode 100644 services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatThemedIconProvider.kt diff --git a/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt b/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt index b1871f84..42c2b233 100644 --- a/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt +++ b/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt @@ -16,9 +16,6 @@ interface IconDao { @Query("SELECT * FROM Icons WHERE componentName = :componentName AND iconPack = :iconPack AND (type = 'app' OR type = 'calendar') LIMIT 1") suspend fun getIcon(componentName: String, iconPack: String): IconEntity? - @Query("SELECT * FROM Icons WHERE componentName = :componentName AND (type = 'themed-compat') LIMIT 1") - suspend fun getCompatThemedIcon(componentName: String): IconEntity? - @Query("SELECT * FROM Icons WHERE componentName = :componentName AND (type = 'app' OR type = 'calendar')") suspend fun getIconsFromAllPacks(componentName: String): List @@ -80,9 +77,6 @@ interface IconDao { @Query("DELETE FROM IconPack WHERE packageName NOT IN (:packs)") fun deleteAllPacksExcept(packs: List) - @Query("DELETE FROM Icons WHERE type = 'themed-compat'") - fun deleteAllCompatThemedIcons() - @Transaction fun uninstallIconPacksExcept(packs: List) { deleteAllIconsPackIconsExcept(packs) diff --git a/core/ktx/src/main/java/de/mm20/launcher2/ktx/XmlPullParser.kt b/core/ktx/src/main/java/de/mm20/launcher2/ktx/XmlPullParser.kt index b2041adf..cbbeb1df 100644 --- a/core/ktx/src/main/java/de/mm20/launcher2/ktx/XmlPullParser.kt +++ b/core/ktx/src/main/java/de/mm20/launcher2/ktx/XmlPullParser.kt @@ -1,10 +1,13 @@ package de.mm20.launcher2.ktx +import android.util.Log import org.xmlpull.v1.XmlPullParser fun XmlPullParser.skipToNextTag(): Boolean { while (next() != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) return true + if (eventType == XmlPullParser.START_TAG) { + return true + } } return false } \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/DynamicCalendarIcon.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/DynamicCalendarIcon.kt index 3f9db1f4..f7453f25 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/DynamicCalendarIcon.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/DynamicCalendarIcon.kt @@ -3,6 +3,8 @@ package de.mm20.launcher2.icons import android.content.res.Resources import android.graphics.drawable.AdaptiveIconDrawable import androidx.core.content.res.ResourcesCompat +import de.mm20.launcher2.icons.compat.AdaptiveIconDrawableCompat +import de.mm20.launcher2.icons.compat.toLauncherIcon import de.mm20.launcher2.icons.transformations.LauncherIconTransformation import de.mm20.launcher2.ktx.isAtLeastApiLevel import kotlinx.coroutines.Dispatchers @@ -25,66 +27,30 @@ internal class DynamicCalendarIcon( val day = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).dayOfMonth val resId = resourceIds[day - 1] - val drawable = try { - ResourcesCompat.getDrawable(resources, resId, null) - } catch (e: Resources.NotFoundException) { - null - } ?: return@withContext StaticLauncherIcon( - foregroundLayer = TextLayer(day.toString()), - backgroundLayer = ColorLayer() - ) + val adaptiveIcon = AdaptiveIconDrawableCompat.from(resources, resId) - var icon = when { - isThemed && drawable is AdaptiveIconDrawable -> { - if (isAtLeastApiLevel(33) && drawable.monochrome != null) { - return@withContext StaticLauncherIcon( + var icon = if (adaptiveIcon != null) { + adaptiveIcon.toLauncherIcon(themed = isThemed) + } else { + try { + val drawable = ResourcesCompat.getDrawable(resources, resId, null) + + when { + drawable is AdaptiveIconDrawable -> AdaptiveIconDrawableCompat.from(drawable).toLauncherIcon(themed = isThemed) + drawable != null -> StaticLauncherIcon( foregroundLayer = TintedIconLayer( - icon = drawable.monochrome!!, + icon = drawable, scale = 1f, ), - backgroundLayer = ColorLayer() - ) - } else { - return@withContext StaticLauncherIcon( - foregroundLayer = TintedIconLayer( - icon = drawable.foreground!!, - scale = 1.5f, - ), - backgroundLayer = ColorLayer() + backgroundLayer = TransparentLayer, ) + else -> null } - } - isThemed -> { - StaticLauncherIcon( - foregroundLayer = TintedIconLayer( - icon = drawable, - scale = 0.5f, - ), - backgroundLayer = ColorLayer() - ) - } - drawable is AdaptiveIconDrawable -> { - return@withContext StaticLauncherIcon( - foregroundLayer = drawable.foreground?.let { - StaticIconLayer( - icon = it, - scale = 1.5f, - ) - } ?: TransparentLayer, - backgroundLayer = drawable.background?.let { - StaticIconLayer( - icon = it, - scale = 1.5f, - ) - } ?: TransparentLayer, - ) - } - else -> StaticLauncherIcon( - foregroundLayer = StaticIconLayer( - icon = drawable, - scale = 1f, - ), - backgroundLayer = TransparentLayer + } catch (e: Resources.NotFoundException) { + null + } ?: return@withContext StaticLauncherIcon( + foregroundLayer = TextLayer(day.toString()), + backgroundLayer = ColorLayer() ) } diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt index e4fac416..413dfb01 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/IconPackManager.kt @@ -20,7 +20,6 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.toBitmap import de.mm20.launcher2.crashreporter.CrashReporter import de.mm20.launcher2.database.AppDatabase -import de.mm20.launcher2.icons.loaders.CompatThemedIconInstaller import de.mm20.launcher2.icons.loaders.GrayscaleMapInstaller import de.mm20.launcher2.icons.loaders.IconPackInstaller import de.mm20.launcher2.ktx.isAtLeastApiLevel @@ -55,7 +54,6 @@ class IconPackManager( withContext(Dispatchers.IO) { IconPackInstaller(context, appDatabase).installIcons() GrayscaleMapInstaller(context, appDatabase).installIcons() - CompatThemedIconInstaller(context, appDatabase).installIcons() } } @@ -236,37 +234,6 @@ class IconPackManager( ) } - suspend fun getCompatThemedIcon(componentName: ComponentName): LauncherIcon? { - val iconDao = appDatabase.iconDao() - val icon = iconDao.getCompatThemedIcon(componentName.flattenToString()) - ?: return null - - val drawableName = icon.drawable ?: return null - - val res = try { - context.packageManager.getResourcesForApplication(componentName.packageName) - } catch (e: Resources.NotFoundException) { - return null - } catch (e: PackageManager.NameNotFoundException) { - return null - } - - val resourceId = res.getIdentifier(drawableName, null, null) - val drawable = try { - ResourcesCompat.getDrawable(res, resourceId, null) - } catch (e: Resources.NotFoundException) { - return null - } ?: return null - - return StaticLauncherIcon( - foregroundLayer = TintedIconLayer( - icon = drawable, - scale = 1f, - ), - backgroundLayer = ColorLayer() - ) - } - suspend fun getAllIconPackIcons(componentName: ComponentName): List { val iconDao = appDatabase.iconDao() return iconDao.getIconsFromAllPacks(componentName.flattenToString()) @@ -301,7 +268,7 @@ class IconPackManager( iconPack: String, baseIconName: String, themed: Boolean, - ): DynamicCalendarIcon? { + ): LauncherIcon? { val resources = try { context.packageManager.getResourcesForApplication(iconPack) } catch (e: PackageManager.NameNotFoundException) { @@ -313,10 +280,16 @@ class IconPackManager( if (id == 0) return null id }.toIntArray() + + if (themed) { + return ThemedDynamicCalendarIcon( + resources = resources, + resourceIds = drawableIds, + ) + } return DynamicCalendarIcon( resources = resources, resourceIds = drawableIds, - isThemed = themed, ) } @@ -444,12 +417,11 @@ class IconPackManager( val array = resources.obtainTypedArrayOrNull(resId) ?: return null if (array.length() != 31) return null - return DynamicCalendarIcon( + return ThemedDynamicCalendarIcon( resources = resources, resourceIds = IntArray(31) { array.getResourceId(it, 0).takeIf { it != 0 } ?: return null }, - isThemed = true ) } catch (e: Resources.NotFoundException) { } diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt index 1901fd94..5d31914d 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt @@ -16,7 +16,7 @@ import de.mm20.launcher2.data.customattrs.DefaultPlaceholderIcon import de.mm20.launcher2.data.customattrs.ForceThemedIcon import de.mm20.launcher2.data.customattrs.UnmodifiedSystemDefaultIcon import de.mm20.launcher2.icons.providers.CalendarIconProvider -import de.mm20.launcher2.icons.providers.CompatThemedIconProvider +import de.mm20.launcher2.icons.providers.CompatIconProvider import de.mm20.launcher2.icons.providers.CustomIconPackIconProvider import de.mm20.launcher2.icons.providers.CustomThemedIconProvider import de.mm20.launcher2.icons.providers.GoogleClockIconProvider @@ -106,14 +106,14 @@ class IconRepository( Log.w("MM20", "Icon pack ${settings.iconPack} not found") } } - providers.add(GoogleClockIconProvider(context)) - providers.add(CalendarIconProvider(context)) if (settings.themedIcons) { - if (!isAtLeastApiLevel(33)) { - providers.add(CompatThemedIconProvider(iconPackManager)) - } providers.add(ThemedIconProvider(iconPackManager)) } + providers.add(GoogleClockIconProvider(context)) + providers.add(CalendarIconProvider(context, settings.themedIcons)) + if (!isAtLeastApiLevel(33)) { + providers.add(CompatIconProvider(context, settings.themedIcons)) + } providers.add(SystemIconProvider(context, settings.themedIcons)) providers.add(placeholderProvider) cache.evictAll() diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/Module.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/Module.kt index c599d1b3..e8fb6ae5 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/Module.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/Module.kt @@ -1,6 +1,5 @@ package de.mm20.launcher2.icons -import de.mm20.launcher2.icons.compat.ThemedIconsCompatManager import org.koin.android.ext.koin.androidContext import org.koin.dsl.module diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/ThemedDynamicCalendarIcon.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/ThemedDynamicCalendarIcon.kt new file mode 100644 index 00000000..d22b24b0 --- /dev/null +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/ThemedDynamicCalendarIcon.kt @@ -0,0 +1,58 @@ +package de.mm20.launcher2.icons + +import android.content.res.Resources +import android.graphics.drawable.AdaptiveIconDrawable +import androidx.core.content.res.ResourcesCompat +import de.mm20.launcher2.icons.transformations.LauncherIconTransformation +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.time.Instant +import java.time.ZoneId + +internal class ThemedDynamicCalendarIcon( + val resources: Resources, + val resourceIds: IntArray, + private var transformations: List = emptyList(), +) : DynamicLauncherIcon, TransformableDynamicLauncherIcon { + override suspend fun getIcon(time: Long): StaticLauncherIcon = withContext(Dispatchers.IO) { + val day = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).dayOfMonth + val resId = resourceIds[day - 1] + + val drawable = try { + ResourcesCompat.getDrawable(resources, resId, null) + } catch (e: Resources.NotFoundException) { + null + } ?: return@withContext StaticLauncherIcon( + foregroundLayer = TextLayer(day.toString()), + backgroundLayer = ColorLayer() + ) + + var icon = when (drawable) { + is AdaptiveIconDrawable -> StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + icon = drawable.foreground, + scale = 1.5f, + ), + backgroundLayer = ColorLayer() + ) + + else -> StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + icon = drawable, + scale = 0.5f, + ), + backgroundLayer = ColorLayer() + ) + } + + + for (transformation in transformations) { + icon = transformation.transform(icon) + } + return@withContext icon + } + + override fun setTransformations(transformations: List) { + this.transformations = transformations + } +} \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/compat/AdaptiveIconDrawableCompat.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/compat/AdaptiveIconDrawableCompat.kt new file mode 100644 index 00000000..b26630b9 --- /dev/null +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/compat/AdaptiveIconDrawableCompat.kt @@ -0,0 +1,150 @@ +package de.mm20.launcher2.icons.compat + +import android.content.res.Resources +import android.content.res.XmlResourceParser +import android.graphics.drawable.AdaptiveIconDrawable +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import android.util.Log +import android.util.Xml +import android.view.InflateException +import androidx.core.content.res.ResourcesCompat +import de.mm20.launcher2.crashreporter.CrashReporter +import de.mm20.launcher2.icons.ColorLayer +import de.mm20.launcher2.icons.StaticIconLayer +import de.mm20.launcher2.icons.StaticLauncherIcon +import de.mm20.launcher2.icons.TintedIconLayer +import de.mm20.launcher2.ktx.isAtLeastApiLevel +import de.mm20.launcher2.ktx.skipToNextTag +import org.xmlpull.v1.XmlPullParserException +import java.io.IOException + + +data class AdaptiveIconDrawableCompat( + val background: Drawable, + val foreground: Drawable, + val monochrome: Drawable?, +) { + + companion object { + fun from(adaptiveIconDrawable: AdaptiveIconDrawable): AdaptiveIconDrawableCompat { + return AdaptiveIconDrawableCompat( + background = adaptiveIconDrawable.background, + foreground = adaptiveIconDrawable.foreground, + monochrome = if (isAtLeastApiLevel(33)) adaptiveIconDrawable.monochrome else null, + ) + } + + fun from(resources: Resources, resId: Int): AdaptiveIconDrawableCompat? { + var xmlParser: XmlResourceParser? = null + + try { + xmlParser = resources.getXml(resId) + val attrs = Xml.asAttributeSet(xmlParser) + if (!xmlParser.skipToNextTag()) return null + + Log.d("MM20", "xmlParser.name: ${xmlParser.name}") + + if (xmlParser.name != "adaptive-icon") { + return null + } + + var background: Drawable? = null + var foreground: Drawable? = null + var monochrome: Drawable? = null + + while (xmlParser.skipToNextTag()) { + when (xmlParser.name) { + "monochrome" -> { + monochrome = parseLayer(resources, xmlParser, attrs) + } + + "background" -> { + background = parseLayer(resources, xmlParser, attrs) + } + + "foreground" -> { + foreground = parseLayer(resources, xmlParser, attrs) + } + } + } + Log.d( + "MM20", + "background: $background, foreground: $foreground, monochrome: $monochrome" + ) + if (foreground != null && background != null) { + return AdaptiveIconDrawableCompat( + background = background, + foreground = foreground, + monochrome = monochrome, + ) + } + } catch (e: Resources.NotFoundException) { + CrashReporter.logException(e) + return null + } catch (e: IOException) { + CrashReporter.logException(e) + return null + } catch (e: XmlPullParserException) { + CrashReporter.logException(e) + return null + } finally { + xmlParser?.close() + } + return null + } + + @Throws( + XmlPullParserException::class, + IOException::class, + Resources.NotFoundException::class + ) + private fun parseLayer( + resources: Resources, + parser: XmlResourceParser, + attrs: AttributeSet + ): Drawable? { + val drawableId = parser.getAttributeResourceValue( + "http://schemas.android.com/apk/res/android", + "drawable", + 0 + ) + + if (drawableId != 0) { + return ResourcesCompat.getDrawable(resources, drawableId, null) + } + if (!parser.skipToNextTag()) return null + return try { + Drawable.createFromXmlInner(resources, parser, attrs) + } catch (e: InflateException) { + CrashReporter.logException(e) + null + } + } + } +} + +fun AdaptiveIconDrawableCompat.toLauncherIcon( + themed: Boolean = false, +): StaticLauncherIcon { + if (themed && this.monochrome != null) { + return StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + scale = 1f, + icon = this.monochrome, + ), + backgroundLayer = ColorLayer() + ) + } else { + return StaticLauncherIcon( + foregroundLayer = StaticIconLayer( + scale = 1.5f, + icon = this.foreground, + ), + backgroundLayer = StaticIconLayer( + scale = 1.5f, + icon = this.background, + ) + ) + } +} \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/compat/ThemedIconCompat.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/compat/ThemedIconCompat.kt deleted file mode 100644 index 4fcbf008..00000000 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/compat/ThemedIconCompat.kt +++ /dev/null @@ -1,26 +0,0 @@ -package de.mm20.launcher2.icons.compat - -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.pm.ActivityInfo -import android.content.pm.PackageManager -import android.content.res.Resources -import android.content.res.XmlResourceParser -import android.util.Log -import de.mm20.launcher2.crashreporter.CrashReporter -import de.mm20.launcher2.icons.IconPackIcon -import de.mm20.launcher2.ktx.isAtLeastApiLevel -import de.mm20.launcher2.ktx.skipToNextTag -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.xmlpull.v1.XmlPullParserException -import java.io.IOException - - -internal class ThemedIconsCompatManager( - private val context: Context, -) { - - -} \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/loaders/CompatThemedIconInstaller.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/loaders/CompatThemedIconInstaller.kt deleted file mode 100644 index 8c699568..00000000 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/loaders/CompatThemedIconInstaller.kt +++ /dev/null @@ -1,109 +0,0 @@ -package de.mm20.launcher2.icons.loaders - -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.pm.ActivityInfo -import android.content.pm.PackageManager -import android.content.res.Resources -import android.content.res.XmlResourceParser -import de.mm20.launcher2.crashreporter.CrashReporter -import de.mm20.launcher2.database.AppDatabase -import de.mm20.launcher2.icons.IconPackIcon -import de.mm20.launcher2.ktx.isAtLeastApiLevel -import de.mm20.launcher2.ktx.skipToNextTag -import org.xmlpull.v1.XmlPullParserException -import java.io.IOException - -class CompatThemedIconInstaller( - private val context: Context, - private val database: AppDatabase, -) { - fun installIcons() { - if (isAtLeastApiLevel(33)) return - val launcherActivities = getLauncherActivities() - - val dao = database.iconDao() - - val icons = mutableListOf() - database.runInTransaction { - dao.deleteAllCompatThemedIcons() - for (activity in launcherActivities) { - val componentName = ComponentName(activity.applicationInfo.packageName, activity.name) - val monochromeIcon = getMonochromeIconResource(activity) - - if (monochromeIcon != null) { - val icon = IconPackIcon( - type = "themed-compat", - componentName = componentName, - name = null, - drawable = monochromeIcon, - iconPack = componentName.packageName - ) - icons.add(icon) - } - - if (icons.size > 100) { - dao.insertAll(icons.map { it.toDatabaseEntity() }) - icons.clear() - } - } - if (icons.isNotEmpty()) { - dao.insertAll(icons.map { it.toDatabaseEntity() }) - } - } - } - - private fun getMonochromeIconResource(activityInfo: ActivityInfo): String? { - val iconResource = activityInfo.iconResource - val resources = try { - context.packageManager.getResourcesForApplication(activityInfo.packageName) - } catch (e: PackageManager.NameNotFoundException) { - CrashReporter.logException(e) - return null - } - var xmlParser: XmlResourceParser? = null - try { - xmlParser = resources.getXml(iconResource) - if (!xmlParser.skipToNextTag()) return null - - if (xmlParser.name != "adaptive-icon") { - return null - } - - while (xmlParser.skipToNextTag()) { - if (xmlParser.name == "monochrome") { - val drawable = xmlParser.getAttributeResourceValue( - "http://schemas.android.com/apk/res/android", - "drawable", - 0 - ) - if (drawable == 0) return null - return resources.getResourceName(drawable) - } - } - } catch (e: Resources.NotFoundException) { - CrashReporter.logException(e) - return null - } catch (e: IOException) { - CrashReporter.logException(e) - return null - } catch (e: XmlPullParserException) { - CrashReporter.logException(e) - return null - } finally { - xmlParser?.close() - - } - - return null - } - - private fun getLauncherActivities(): List { - val resolveInfos = context.packageManager.queryIntentActivities( - Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), 0 - ) - - return resolveInfos.mapNotNull { it.activityInfo } - } -} \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CalendarIconProvider.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CalendarIconProvider.kt index 4146a5c2..1be000ee 100644 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CalendarIconProvider.kt +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CalendarIconProvider.kt @@ -9,7 +9,7 @@ import de.mm20.launcher2.ktx.obtainTypedArrayOrNull import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.search.data.LauncherApp -class CalendarIconProvider(val context: Context): IconProvider { +class CalendarIconProvider(val context: Context, val themed: Boolean): IconProvider { override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? { if(searchable !is LauncherApp) return null val component = ComponentName(searchable.`package`, searchable.activity) @@ -40,7 +40,8 @@ class CalendarIconProvider(val context: Context): IconProvider { typedArray.recycle() return DynamicCalendarIcon( resources = resources, - resourceIds = drawableIds + resourceIds = drawableIds, + isThemed = themed ) } } \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatIconProvider.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatIconProvider.kt new file mode 100644 index 00000000..eef72519 --- /dev/null +++ b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatIconProvider.kt @@ -0,0 +1,39 @@ +package de.mm20.launcher2.icons.providers + +import android.content.ComponentName +import android.content.Context +import android.content.pm.PackageManager +import de.mm20.launcher2.icons.LauncherIcon +import de.mm20.launcher2.icons.compat.AdaptiveIconDrawableCompat +import de.mm20.launcher2.icons.compat.toLauncherIcon +import de.mm20.launcher2.search.SavableSearchable +import de.mm20.launcher2.search.data.LauncherApp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class CompatIconProvider( + private val context: Context, + private val themed: Boolean = false, +) : IconProvider { + override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? { + if (searchable !is LauncherApp) return null + val component = ComponentName(searchable.`package`, searchable.activity) + val activityInfo = try { + context.packageManager.getActivityInfo(component, 0) + } catch (e: PackageManager.NameNotFoundException) { + return null + } + val iconRes = activityInfo.iconResource + val resources = try { + context.packageManager.getResourcesForApplication(activityInfo.packageName) + } catch (e: PackageManager.NameNotFoundException) { + return null + } + + val icon = withContext(Dispatchers.IO) { + AdaptiveIconDrawableCompat.from(resources, iconRes) + } ?: return null + + return icon.toLauncherIcon(themed = themed) + } +} \ No newline at end of file diff --git a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatThemedIconProvider.kt b/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatThemedIconProvider.kt deleted file mode 100644 index 878f7630..00000000 --- a/services/icons/src/main/java/de/mm20/launcher2/icons/providers/CompatThemedIconProvider.kt +++ /dev/null @@ -1,17 +0,0 @@ -package de.mm20.launcher2.icons.providers - -import android.content.ComponentName -import de.mm20.launcher2.icons.IconPackManager -import de.mm20.launcher2.icons.LauncherIcon -import de.mm20.launcher2.search.SavableSearchable -import de.mm20.launcher2.search.data.LauncherApp - -class CompatThemedIconProvider( - private val iconPackManager: IconPackManager, -): IconProvider { - override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? { - if (searchable !is LauncherApp) return null - val component = ComponentName(searchable.`package`, searchable.activity) - return iconPackManager.getCompatThemedIcon(component) - } -} \ No newline at end of file